2013-03-01 94 views
1

我有这个测试应用程序应该打印“过滤”和“改变”每次点击应用程序视图,因为计算属性被调用。然而属性结合使用空数组更新属性时才触发:ComputedProperty没有得到更新

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

为什么设置设置为空数组时属性绑定,才触发?为什么在超时时手动进行触发呢?

更新

这里是一个工作jsbin:http://jsbin.com/edolol/11/edit

回答

2

当你要添加/从阵列中删除项目,而不是改变整个数组,你需要告知物业计算,观察该数组里面的物品,不仅数组本身:

的语法是:

function() { 
}.property('[email protected]') 

它与setTimeout工作的原因是因为你是更换整个阵列,而不是里面的物品。

我定你的jsbin:http://jsbin.com/edolol/10/edit

我修正了一些小的其他的东西,如filter.push现在filter.pushObject(使用Ember的MutableArray)。

而改变滤波器阵列(filter = filter.filter()),你需要新的filter变量设置为属性后:App.set('Settings.filter', filter);

+0

是从[]到MutableArray自动发生转换?没有你的小修改,'。@ each'的东西就无法工作(正如你可以看到你是否从jsbin的修订版本3到版本9一样循环)。 – ohcibi 2013-03-01 13:48:04

+2

是的,Ember将所有数组自动转换为'MutableArray'。你可以定义一个数组var a = [],并使用'a.forEach','a.pushObject','a.find'和所有其他函数。 – 2013-03-01 13:57:35

0

的问题是,我已经使用.push()添加到App.Settings.filter.filter()从而除去。第一种方法不会创建一个新的数组,后者会这样做。这就是为什么从该阵列中删除已经工作,但没有添加。

我假设使用Ember.ArrayProxy和观察者为[email protected]会工作。但那是出于我的知识。这个小问题可以通过创建一个新的数组来解决。

filter = App.get('Settings.filter').slice(0);