Javascript 余烬中控制器上的计算vs观察

Javascript 余烬中控制器上的计算vs观察,javascript,ember.js,Javascript,Ember.js,我一直认为.observes('someProperty')和.property('someProperty')的工作原理完全相同,只是前者用于触发函数调用,后者用于使对象属性保持最新 但现在我有个问题。我的控制器代码如下所示: _logChange: function(){ console.log('model array observer fired'); }.observes('model.@each'), statsData: function(){ console.l

我一直认为
.observes('someProperty')
.property('someProperty')
的工作原理完全相同,只是前者用于触发函数调用,后者用于使对象属性保持最新

但现在我有个问题。我的控制器代码如下所示:

_logChange: function(){
    console.log('model array observer fired');
}.observes('model.@each'),

statsData: function(){
    console.log('statsData being updated');
    ...
    return someArray;
}.property('model.@each')
观察者和computed属性都监视模型。@但由于某种原因,观察者在每次模型更改时都会触发,并且属性在神秘消失之前只更新两次。
statsData
在初始页面加载时计算一次,在第一次路由转换时计算一次,然后在之后,所有的转换(以及它们在基础
模型中所做的更改)都不会影响它

这是怎么回事?他们不应该以同样的方式应对变化吗


请注意,我正在模板中使用
statsData
属性

观察者立即开火,作为运行循环的一部分计算用户的开火,并以非抖动方式进行调度。目前,您所关注的只是向集合中添加或删除项目,而不是集合中某个项目的属性是否已更改。如果要查看特定属性,则需要指定它

statsData: function(){
    console.log('statsData being updated');
    ...
    return someArray;
}.property('model.@each.cost')
如果您只想观看收藏的变化,您只需使用
[]

statsData: function(){
    console.log('statsData being updated');
    ...
    return someArray;
}.property('model.[]')

多亏了Ember IRC上那些可爱的人,我才能够弄明白。问题是我将
statsData
传递给一个组件,就像这样:
{{common statistics values=statsData}}
在该组件中,我有以下函数:

_validateValues: function(){
    var values = this.get('values');
    if(!values || !Ember.isArray(values) || values.length === 0)
    {
        this.set('values',[]);
    }
}.on('willInsertElement')
正如您所看到的,如果组件不期望设置值,则设置值。不幸的是,这也影响了控制器上的
statsData
,这要归功于。通过在组件中设置
statsData
,我破坏了控制器上的computed属性


所以余烬根本就不是问题。我只是没有意识到Ember对象上的对象属性的行为与“常规JavaScript对象”上的行为相同。

谢谢你的回答,我不知道观察者在运行循环中立即触发与computed在运行循环中触发。我也不知道@each和[]之间的真正区别。好消息!不过,我确实解决了我的问题,结果证明根本不是余烬问题。我发布了一个答案。我想补充的是,我在计算属性中没有为
值定义setter逻辑,这就是为什么计算属性被破坏的原因;它被一个普通的JS数组完全覆盖。必须记住,计算属性中的setter逻辑!