我有这个测试应用程序,每次单击应用程序视图时都应该打印“过滤”和“更改”,因为调用了计算属性。但是,只有在使用空数组更新属性时才会触发属性绑定:
window.App = Ember.Application.create({
Settings: Ember.Object.create({
filter: []
}),
ApplicationView: Ember.View.extend({
click: function(event) {
filter = App.get('Settings.filter');
console.dir(filter);
if (App.get('Room.filtered')) {
filter = filter.filter(function(item) {
return item != App.get('Room.name');
});
} else {
filter.push(App.get('Room.name'));
}
App.set('Settings.filter', filter);
}
})
});
Room = Ember.Object.extend({
name: "test",
_filterer: function() {
console.dir("changed");
}.observes('filtered'),
filtered: function() {
console.dir("filtered");
filter = App.get('Settings.filter');
for (var i = 0; i < filter.length; i++) {
if (filter[i] == this.get('name')) return true;
}
return false;
}.property('App.Settings.filter', 'name').volatile()
});
App.Room = Room.create();
setTimeout(function() {App.set('Settings.filter', ['test']); }, 3000);
这是jsbin:http://jsbin.com/edolol/2/edit
为什么仅在将Setting设置为空数组时才触发属性绑定?为什么在超时时手动执行它会触发?
这是一个有效的jsbin:http://jsbin.com/edolol/11/edit
答案 0 :(得分:3)
当您要从数组中添加/删除项目而不更改整个数组时,您需要通知计算属性以观察数组内的项目,而不仅仅是数组本身:
语法为:
function() {
}.property('App.settings.filter.@each')
它使用setTimeout
的原因是因为您要替换整个数组而不是其中的项目。
我修复了你的jsbin:http://jsbin.com/edolol/10/edit
我修复了其他一些小问题,例如filter.push
现在是filter.pushObject
(使用Ember的MutableArray
)。
更改过滤器数组(filter = filter.filter()
)后,您需要将新的filter
变量设置为属性:App.set('Settings.filter', filter);
答案 1 :(得分:0)
问题是我使用.push()
添加到App.Settings.filter
和.filter()
以从中删除。第一种方法不会创建新数组,后者会创建。这就是为什么从该阵列中删除有效但不添加。
我认为使用Ember.ArrayProxy
和.@each
的观察者会有效。但那是我所知道的。这个小问题可以通过创建一个新数组来解决。
filter = App.get('Settings.filter').slice(0);