为啥 ember 计算属性只在 ember 检查器中执行一次?

Posted

技术标签:

【中文标题】为啥 ember 计算属性只在 ember 检查器中执行一次?【英文标题】:Why do ember computed properties only execute once in ember inspector?为什么 ember 计算属性只在 ember 检查器中执行一次? 【发布时间】:2016-06-27 11:07:52 【问题描述】:

我有一个演示控制器:

import Ember from 'ember';

export default Ember.Controller.extend(
  firstName: 'Bob',
  lastName: 'Smith',

  emailAddress: 'bobsmith@gmail.com',

  fullName: Ember.computed('firstName', 'lastName', function() 
    console.log('executed!');
    return `$this.get('firstName') $this.get('lastName')`;
  ),

  actualEmailAddress: Ember.computed('emailAddress', function() 
    console.log('actualEmailAddress function is called: ', this.get('emailAddress'));
  )
);

当我在浏览器的本地主机上运行应用程序时,我打开 ember 检查器并运行:

$E.get('actualEmailAddress')

这会返回:

actualEmailAddress function is called: bobsmith@gmail.com

但是当我第二次运行它时,我会得到undefined

当我运行$E.get('fullName')时也是如此

返回

executed!
"Bob Smith"

但是当我再次运行它时,它只返回Bob Smith,而不是console.log

为什么会这样?

谢谢!

【问题讨论】:

【参考方案1】:

计算属性仅按需计算,即如果它在模板中使用 actualEmailAddress 或在 js 代码中使用 this.get('actualEmailAddress');

对于性能计算属性,只有在其依赖属性值发生更改时才会重新计算。所以在第一次计算之后,结果会被缓存,如果你再次尝试访问 CP,它只会返回缓存的值。

actualEmailAddress 的第一种情况下,CP 函数第一次执行并且您记录了您的语句,但您没有返回值,因此隐式返回了undefined。所以下次调用CP时,会返回缓存值undefined

fullName 的第二种情况下,该函数仅在第一次被调用并且语句被记录。这里既然你已经正确地返回了一个值,那么下次你尝试调用 CP 时,你会得到缓存的返回值作为响应。

要强制 CP 重新计算,您需要更改相关属性的值。或者使用一个简单的方法并调用它。

【讨论】:

【参考方案2】:

计算属性是 惰性 缓存。每次运行时,它们都会缓存返回的值,并且不会重新计算它,除非依赖属性之一发生更改,并且再次访问 CP。

这是设计使然。此外,您所看到的并不是 Ember Inspector 所独有的——这适用于所有环境。

更多详情请查看我的answer to your other question。

【讨论】:

【参考方案3】:

计算属性用对象的字面量转换对象字面量 访问器函数到属性中。

默认情况下,支持计算属性的函数只会是 调用一次,结果将被缓存。您可以指定各种 您的计算属性所依赖的属性。这将迫使 如果依赖项被修改,缓存结果将被重新计算。

我推荐使用:

yourProperty: function() 
               
                 //do something before send it back, example:
                 return `$this.get('yourRealProperty')`;
              .property('yourRealProperty'),

这将在您调用 yourProperty 时返回 yourRealProperty 的值。

reference 1 reference 1

【讨论】:

以上是关于为啥 ember 计算属性只在 ember 检查器中执行一次?的主要内容,如果未能解决你的问题,请参考以下文章

Ember.js 在回调中返回计算属性

如何在 Ember 模型单元测试中检查属性属性类型?

Ember 数据模型中的计算属性不适用于 ember-cli-mirage 模型

如何在 Ember.js 中创建计算属性以查看单个 Ember Data 属性是不是脏?

Ember.js、set() 和计算属性

Ember.js:在服务的把手中使用计算属性