我正在使用PolymerJS。
看起来像观察由getter
作品派生的属性。
例如,以下代码似乎有效:
<div>Direct binding to property: {{internalData.value}}</div>
<div>Binding to computed value: {{computedValue}}</div>
<div>Binding to observed value: {{observedValue}}</div>
<script>
var externalData = {
get value() {
return 'static value';
}
};
Polymer('my-element', {
internalData: externalData,
computed: {
computedValue: 'internalData.value'
},
observe: {
'internalData.value': 'valueChanged'
},
valueChanged: function() {
this.observedValue = this.internalData.value;
}
});
</script>
但是,如果我的getter
定义了更复杂的内容怎么办?我发现如果getter
在每次调用时返回一个新值,那么尝试这种绑定会导致我的浏览器选项卡崩溃(这是Chrome 39,所以我认为这是本机对象观察的结果)。 / p>
例如:
var externalData = {
get changingValue() {
return Math.random();
}
}
这是为什么?如果我尝试这种模式,我还应该担心什么?
以下是问题的不同排列的更完整的概述:
http://jsbin.com/reder/28/edit?html,output
请注意,顺便说一句,这个问题可能比你想象的更常见。如果从getter返回一个Object,很容易在每次访问时意外创建一个Object,例如:
var externalData = {
get changingValue() {
return { foo: 'bar' };
}
}
答案 0 :(得分:2)
不是一个完整的答案,但他是一个开始:
考虑changingValueChanged
何时运行。每次changingValue
更改时都会运行。
考虑changingValue
何时发生变化。它每次访问时都会发生变化。
理解崩溃的最后一件事是changingValueChanged
访问changingValue
:
this.observedChangingValue = this.internalData.changingValue;
当访问该赋值的值时,您更改该值并让侦听器再次运行,这将永远重复。
看起来你无法有意义地观察到每次访问总是不同的值。没有提到在你知道它变化后尝试捕获该变量的值是没有意义的:变量在功能上是一个生成器。你不能问变量它刚才有什么价值,因为它只能给你新的价值。另一方面,可以观察基于getter的变量,该变量偶尔会发生变化,因为它会根据访问该值的行为之外的其他内容更改其值。
如果您更改您的侦听器以执行与变量无关的操作(例如,只执行console.log("hello")
)并且永远不会访问this.internalData.changingValue
,则不会有无限循环。请注意,新观察值位于提供给更改侦听器的第一个参数中,因此您可以安全地获取该值。但是,这不是Polymer最终在页面上显示的值;看来Polymer再次访问了读取值以将其放入DOM中。
但请注意,当您在控制台中访问externalData.changingValue
时,更改侦听器似乎无法运行,但在访问externalData
时 运行显示对象的所有属性。
我无法说明为什么compute
属性会崩溃页面,因为我不知道那是什么。