Problem
I've often used this kind of computed properties where the setter simply returns the new value :
@computed('args.myValue')
get myValue() {
return this.args.myValue;
}
set myValue(newValue) {
return newValue; // <==== this is no longer valid with native setter
}
This does few things :
- Set initial value to
args.myValue
- Allow to change the value (typically through an
<Input @value= />
) - Restore the default value when
args.myValue
changes
The problem comes with native setters which can't return
any value.
Notice I could probably find a "hackish" solution but I'd like to have code that follows new EmberJS conventions in order to avoid painfull later updates.
Things I tried
Manual caching
@tracked _myValue = null;
get myValue() {
return this._myValue || this.args.myValue;
}
set myValue(newValue) {
this._myValue = newValue;
}
This does not work because _myValue
is always set after the first myValue=(newValue)
. In order to make it work, there should be some kind of observer which resets it to null
on args.myValue
change.
Sadly, observers are no longer part of EmberJS with native classes.
helper
<Input @value= />
As expected, it does not work because it just doesn't update myValue
.
helper combined with event.target.value
handling
<Input @value= />
get myValue() {
return this.args.myValue;
}
@action keyPressed(event) {
this.doStuffThatWillUpdateAtSomeTimeMyValue(event.target.value);
}
But the Input
is still not updated when the args.myValue
changes.
Initial code
Here is a more concrete use example :
Component
// app/components/my-component.js
export default class MyComponent extends Component {
@computed('args.projectName')
get projectName() {
return this.args.projectName;
}
set projectName(newValue) {
return newValue; // <==== this is no longer valid with native setter
}
@action
searchProjects() {
/* event key stuff omitted */
const query = this.projectName;
this.args.queryProjects(query);
}
}
<Input @value= />
Controller
// app/controllers/index.js
export default class IndexController extends Controller {
get entry() {
return this.model.entry;
}
get entryProjectName() {
return this.entry.get('project.name');
}
@tracked queriedProjects = null;
@action queryProjects(query) {
this.store.query('project', { filter: { query: query } })
.then((projects) => this.queriedProjects = projects);
}
@action setEntryProject(project) {
this.entry.project = project;
}
}
<MyComponent
@projectName=
@searchProjects= />
When the queriedProjects
are set in the controller, the component displays them.
When one of those search results is clicked, the controller updates the setEntryProject
is called.
Aucun commentaire:
Enregistrer un commentaire