检测阵列突变

时间:2016-04-03 14:34:06

标签: javascript arrays polymer-1.0 mutation

我制作了一个简单的概念验证Polymer 1.0应用程序来演示我的问题:JSBin

在我的问题中,我使用array mutation methods来更改数组,其中包含购物项列表。

然而,这似乎并没有按预期发挥作用。我dom-repeat中进行更改并在打印数组长度时进行更改。 在我打印数组本身时或在将其包装在函数中时获取更改事件。

简而言之,为什么这样做?

<p>Number of items: [[list.length]]</p>

为什么有效?

<p>Items inline: [[list]]</p>    
<p>Observe function : [[_observe(list)]]</p>

同样,当我取消注释以下行(在JSBin中)时,事情似乎工作为无效。但我不喜欢它,因为它有点像hackish。

app.notifyPath('list', app.list.slice());

我通过阅读此问题偶然发现slice()修正:https://github.com/Polymer/polymer/issues/2068

修改

因此,在审阅了评论之后,回答问题&#34;这是设计和#34;是是的。数组本身没有变化(因为它只是一个参考),但它的属性会发生变化。这就是slice()强制重新加载的原因,因为它会创建一个浅层副本。

然而,人们可能会争论这是否正常。是的,变量list不会改变本身。但是将[[list]]放入HTML代码实际上会触发toString()。该函数的结果更改。

我想我现在仍然躲在length财产上......

1 个答案:

答案 0 :(得分:2)

正如评论中所提到的,notifyPathslice调用正在创建数组的浅表副本,并将不同的引用分配回list变量 - 触发更新捆绑。如果不维护单独的(watchable)变量或者弄乱对象引用,我能想到的唯一其他解决方法是捎带list.length属性而不是列表本身并传递通过某种“格式化”功能。 例如

<p>Items inline: [[format(list.length)]]</p>
app.format = function(){
    return app.list.toString();
};

» Fiddle

正如@zb所指出的那样,您可以对此进行扩展,并通过将相关变量作为参数传递,使该函数可以重用于任何数组:

<p>Items inline: [[format(list, list.length)]]</p>
app.format = function(list){
    return list.toString();
};

» Fiddle