我创建了一个简单的原型来显示和编辑人员列表。原型可以在这里找到:JSBin。
正如您所看到的,当" Save"按下后,使用array mutation API将项目写回数组。我不确定这是否真的需要,因为对象总是通过引用分配。
然而," Save"按钮不更新列表中的项目。 但是再次编辑时,新更改的值会以某种方式保留在表单中。我猜这种变化确实发生在内存中,但dom-repeat
不会触发列表的新渲染。
我还在observe
上设置了dom-repeat
属性,但似乎没有任何区别。
我的问题是双重的:
答案 0 :(得分:2)
简答:将保存功能切换为此
app.save = function(e) {
app.splice('people', app.selectedIndex, 1, {name: app.selected.name, surname: app.selected.surname});
app.selectedIndex = -1;
};
答案很长:
您需要这样做的原因有点复杂,但它与dom-repeat内部的性能优化有关。当dom-repeat的数组得到更新时,它不会简单地删除所有子节点并重新渲染所有内容,因为这可能很昂贵。相反,它循环遍历当前作为子项的所有模板实例,并检查其项目模型是否已更改。对于每个模板,它执行引用相等性检查以查看它们是否是同一个对象。如果他们是相同的,它什么都不做。如果不是,则重新呈现该模板。
在您的情况下,您使用已存在的同一对象拼接数组。因此,当dom-repeat执行此优化检查时,它会看到该项与之前的对象相同,并且不执行任何操作。但是,如果创建一个新对象,则此检查将失败,并且它将重新呈现模板实例...因此,它可以正常工作。
现在,为什么它不会在对象变异时更新?对此的回答必须归结于Polymer的数据检查基于'路径通知',而不是像脏检查那样昂贵的事情。当属性更新时,Polymer会将事件触发到与该属性绑定数据的每个子节点。问题是,您的表单不是作为'people'数组中的元素绑定到属性的数据。他们被一个不同的财产绑定,“被选中”。即使它们由同一个对象支持,属性名称也不同,因此通知路径不匹配; app.selected.name
是在您更改John Doe的名字时收到通知的路径,而不是app.people.0.name
,这是dom-repeat正在寻找更改通知的路径。
关于问题的第二部分,我建议您尽可能避免双向数据绑定。它不像Angular那样依赖脏检查,所以它不是一个性能问题,但它确实有很多开销。