Ember中控制器的计算与观察

时间:2015-02-05 15:16:25

标签: javascript ember.js

我始终认为.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')

观察者和计算属性都是监视模型。@但由于某种原因,观察者会在每次模型更改时触发,并且属性仅在神秘地死亡之前更新TWICE。 statsData是在初始页面加载时计算一次,在第一次路径转换时计算一次,然后在此之后,没有任何转换(它们所做的基础model中的更改)会影响它。

这里发生了什么?他们不应该以同样的方式回应变化吗?

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

2 个答案:

答案 0 :(得分:2)

感谢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对象上的对象属性与它们对“常规JavaScript对象”的行为方式相同。

答案 1 :(得分:1)

观察员立即开火,计算出火焰作为跑步循环的一部分,并以去抖动的方式安排。目前,您正在观看的是您在集合中添加或删除项目,而不是集合中其中一个项目的属性是否已更改。如果您想要观看特定属性,则需要指定它。

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

如果您只想观看收藏品的更改,请使用[]

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