考虑以下Ember对象:
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 },
});
然后,在应用程序的某个时刻,我们希望将filterState
值设置为一组新值。考虑以下三种替代方案来实现这一目标:
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]);
});
// UPDATE:
// The following alternative is equivalent to the one just above,
// and therefore has the same shortcomings
filterState.
get('values').
setProperties(newFilterValues);
正如评论所强调的那样,第一个替代方案完成了工作,但它“错误地”触发了观察者,即使values.department_id
属性没有真正改变。
第二种和第三种选择不会触发观察者,但两者都有一个更大的缺陷:新的过滤器值集中不存在的属性不会从{{1对象。
目前第一个是我可以使用的唯一选项,因为第二个替代方案的缺陷是不可接受的。但是,如果没有必要,观察者不应该开火。
我的替代方案是:
filterState.values
对象中的新值,其中观察者不会被触发,但是它也会按照预期的方式设置/取消设置所有内容吗? / LI>
醇>
答案 0 :(得分:0)
将values
定义为Ember.Object:
filterState: FilterState.create({
values: Ember.Object.create({
department_id: 5, manager_id: 3
})
})
然后它起作用,例如:
actions: {
// will run observer only if department_id is changed
changeDepartment: function(value) {
var filterStateValues = this.get('filterState.values');
filterStateValues.set('department_id', value);
},
// will not run observer
changeOthers: function() {
var filterStateValues = this.get('filterState.values');
filterStateValues.setProperties({
manager_id: 12
});
}
}