检测阵列突变

Detect array mutation

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

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

但是,这似乎没有按预期工作。我 dodom-repeat 和打印数组长度时得到了改变。 但是不会在打印数组本身或将其包装在函数中时得到更改事件。

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

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

为什么这个有效?

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

,当我取消注释以下行(在 JSBin 中)时,事情似乎按缩进的方式工作。但我不喜欢它,因为它有点老套。

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

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


编辑

因此,在查看评论后,"Is this by design" 问题的答案是肯定的。数组本身并没有改变(因为它只是一个参考),但是它 属性 do 改变了。这就是 slice() 强制重新加载的原因,因为它创建了一个浅拷贝。

但是,有人可能会争论这是否可行。是的,变量 list 不会改变 本身 。但是把[[list]]放在HTML代码中实际上会触发toString()。该函数的结果 更改。

我想我现在一直在使用 length 属性...

正如评论中提到的,notifyPathslice 调用正在创建数组的浅表副本并将不同的引用分配回 list 变量 - 触发更新的绑定。在不维护单独的 (watchable) 变量或乱用对象引用的情况下,我能想到的唯一其他解决方法是搭载 list.length 属性而不是列表本身,并通过某种 "formatting" 函数传递它。 例如

<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