为啥 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 数据模型中的计算属性不适用于 ember-cli-mirage 模型