Consider the following Ember object:
const FilterState = Ember.Object.extend({
values: null,
departmentChanged: Ember.observer('values.department_id', function() {
// do something when the department changes
}),
});
const filterState = FilterState.create({
values: { department_id: 5, manager_id: 3 },
});
Then at some point in the app, we want to set the filterState values to a new set of values. Consider the following two alternatives to achieve this:
const newFilterValues = { department_id: 5 };
// This will unset the manager_id value, which is the desired behavior.
// However, it will trigger the departmentChanged observer,
// even though the department_id didn't actually change
filterState.set('values', newFilterValues);
// The following alternative won't trigger the observer, like intended
// but it won't unset the manager_id, which is necessary to happen
const filterValues = filterState.get('values');
Object.keys(newFilterValues).forEach(function(key) {
filterValues.set(key, newFilterValues[key]);
});
As the comments highlight, the first alternative gets the job done, but it "incorrectly" triggers the observer, even though the values.department_id property didn't really change.
The second alternative does not trigger the observer, but has a bigger flaw: It does not unset the properties that are not present in the new set of filter values.
Currently the first one is the only option I can use, because the flaw on the second alternative is unacceptable. However, it would be desirable to not have the observer fire if it isn't really necessary.
My alternatives are:
- I could try to cache the previous values and manually check inside the observer if the value really changed, but this seems too verbose and lame (this is what I'm currently doing).
- Isn't there a way for Ember observer mechanism to pass the old values in the observer callback?
- Or better yet, it there a way to achieve observers that will only fire if the properties really changed? (perhaps with some mixin magic?)
- Or finally, is there some other way to set the new values from the
newFilterValuesobject, in which the observer is not fired, but so that it also sets/unsets everything in the way it is intended?
Aucun commentaire:
Enregistrer un commentaire