在 Ember 中在控制器上计算与观察

Computed vs Observes on Controller in Ember

我一直认为.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')

观察者和计算 属性 都观察模型。@each 但是由于某种原因,观察者在每次模型更改时都会触发,并且 属性 在神秘地进行之前只更新两次dead. statsData 在初始页面加载时计算一次,在第一个路由转换时计算一次,然后是 none 转换(底层 model 他们使)影响它。

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

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

观察者立即开火,计算的开火作为 运行 循环的一部分,并以去抖动的方式安排。当前,您所关注的只是您向 collection 添加或删除了一项,而不是 collection 中其中一项的 属性 是否已更改。如果您想观看特定的属性,您需要指定它。

statsData: function(){
    console.log('statsData being updated');
    ...
    return someArray;
}.property('model.@each.cost')

如果您只想观看 collection 的变化,您应该使用 []

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')

如您所见,如果它不是组件所期望的,则设置 values。不幸的是,由于 this JavaScript language feature,这也影响了控制器上的 statsData。通过在组件中设置 statsData,我打破了控制器上计算的 属性。

所以 Ember 从来都不是问题。我只是没有意识到 Ember 对象上的对象属性的行为与 "regular JavaScript objects."

上的行为相同