Nat*_*man 7 javascript ember.js
我不太确定为什么我的计算属性没有返回更新的值.
我有一个用户可以点击的选项列表,操作更新控制器的属性,即Ember对象.我有一个循环遍历对象的计算属性,查找具有该Ember对象属性的非空值的键,如果找到一个,则返回false,否则返回true.
这是东西:
App.SimpleSearch = Ember.Object.extend({
init: function() {
this._super();
this.selectedOptions = Ember.Object.create({
"Application" : null,
"Installation" : null,
"Certification" : null,
"Recessed Mount" : null,
"Width" : null,
"Height" : null,
"Heating" : null,
"Power" : null
});
},
selectedOptions: {},
numOfOptions: 0,
allOptionsSelected: function() {
var selectedOptions = this.get('selectedOptions');
for (var option in selectedOptions) {
console.log(selectedOptions.hasOwnProperty(option));
console.log(selectedOptions[option] === null);
if (selectedOptions.hasOwnProperty(option)
&& selectedOptions[option] === null) return false;
}
return true;
}.property('selectedOptions')
});
App.SimpleSearchRoute = Ember.Route.extend({
model: function() {
return App.SimpleSearch.create({
'SimpleSearchOptions': App.SimpleSearchOptions,
'numOfOptions': App.SimpleSearchOptions.length
});
},
setupController: function(controller, model) {
controller.set('model', model);
}
});
App.SimpleSearchController = Ember.ObjectController.extend({
getProductsResult: function() {
var productsFromQuery;
return productsFromQuery;
},
setSelection: function (option, selectionValue) {
this.get('selectedOptions').set(option, selectionValue);
this.notifyPropertyChange('allOptionsSelected');
},
actions: {
registerSelection: function(option) {
console.log('registering selection');
console.log(this.get('allOptionsSelected'));
console.log(this.get('selectedOptions'));
this.setSelection(option.qname, option.value);
},
Run Code Online (Sandbox Code Playgroud)
在控制器的作用下,registerSelection被烧成就好了,但我只看到了console.log从SimpleSearch模型一次.一旦第一次计算属性,之后就不会注意了,这意味着计算属性不会在selectedOptions每次调用时观察到的更改:
setSelection: function (option, selectionValue) {
this.get('selectedOptions').set(option, selectionValue);
this.notifyPropertyChange('allOptionsSelected');
},
Run Code Online (Sandbox Code Playgroud)
编辑:
我实际上解决了我的问题,没有改变什么
我改变了以下行:
this.notifyPropertyChange('allOptionsSelected');
Run Code Online (Sandbox Code Playgroud)
至:
this.get('model').notifyPropertyChange('selectedOptions');
Run Code Online (Sandbox Code Playgroud)
notifyPropertyChange 需要在模型(或具有特定属性的观察者的Ember对象)的上下文中调用,并且作为参数发送的字符串是已更新的属性的名称.
在我做出改变后,它按预期工作.
Ember不会观察对象的任何变化,它会观察到一个属性.
这对你有什么影响?那么你正在观察这个方法selectedOptions,但是这个对象本身仍然是同一个对象,你可能正在改变它的属性,而不是对象本身.然后你告诉Ember allOptionsSelected已经改变了控制器的范围,所以它重新计算它,但它不会重新计算它,因为它不是脏的,它只是改变了.你真的想说selectedOptions改变了allOptionsSelected以重新计算它的价值.不幸的是,你在控制器的范围内这样做,所以告诉控制器属性已经改变并不重要.
allOptionsSelected: function() {
var selectedOptions = this.get('selectedOptions');
for (var option in selectedOptions) {
console.log(selectedOptions.hasOwnProperty(option));
console.log(selectedOptions[option] === null);
if (selectedOptions.hasOwnProperty(option)
&& selectedOptions[option] === null) return false;
}
return true;
}.property('selectedOptions')
Run Code Online (Sandbox Code Playgroud)
这是一个虚拟示例,显示了实际更新的原因.
http://emberjs.jsbin.com/iCoRUqoB/1/edit
老实说,既然你没有看特定的属性,我可能会做一个数组,或者在对象上创建一个处理添加/删除/修改属性的方法,这样你就可以从它的范围内触发一个属性更改来更新所有的父监听器.变化.