【问题标题】:Polymer 1.0: Best practice for managing a simple list of itemsPolymer 1.0:管理简单项目列表的最佳实践
【发布时间】:2016-04-06 11:28:48
【问题描述】:

我创建了一个简单的原型来显示和编辑人员列表。原型可以在这里找到:JSBin

如您所见,当按下“保存”时,使用array mutation API 将项目写回数组。我不确定这是否真的需要,因为对象总是通过引用分配的。

但是,“保存”按钮不会更新列表中的项目。 但是当您再次编辑它时,新更改的值会以某种方式保留在表单中。我猜更改确实发生在内存中,但dom-repeat 不会触发列表的新呈现。

我还在dom-repeat 上设置了observe 属性,但似乎没有任何区别。

我的问题有两个

  1. 需要更改哪些内容才能在保存项目时更新列表。
  2. 是否有更好的方法(常见的最佳实践)来管理项目列表(使用双向数据绑定)。

【问题讨论】:

标签: javascript list polymer-1.0


【解决方案1】:

简短回答:将您的保存功能切换到此

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 做这个优化检查时,它会看到 item 和之前是同一个对象,什么也不做。但是,如果您创建一个新对象,此检查将失败,它将重新渲染模板实例......因此,它可以工作。

现在,为什么当对象发生变异时它不更新?答案必须归因于 Polymer 的数据检查是基于“路径通知”的事实,而不是像脏检查这样昂贵的东西。当一个属性被更新时,Polymer 会向每个与该属性数据绑定的子节点触发一个事件。问题是,您的表单没有作为“人员”数组中的元素与属性数据绑定。它们绑定到不同的属性,“选定”。即使它们由同一个对象支持,但属性名称不同,因此通知路径不匹配; app.selected.name 是当您更改 John Doe 的名字时收到通知的路径,而不是 app.people.0.name,这是 dom-repeat 正在寻找更改通知的路径。

至于您问题的第二部分,我建议您尽可能避免双向数据绑定。它不像 Angular 那样依赖脏检查,所以它不是一个巨大的性能问题,但它仍然有很多开销。

【讨论】:

  • 因为我的拼接没用(对象已经在那里),只需调用notifyPath 就可以了?还是创建对象的浅表副本是唯一的解决方案?编辑简单项目列表的解决方案是什么?您将如何将对象传递给表单以及如何将其复制回来?您说要避免双向数据绑定,如何实现呢?每次都做浅拷贝?
  • 我确信更改字段上的 notifyPath 也将起作用。我一直使用不可变对象并在新副本中进行拼接,因为在我正在开发的应用程序中,我们正在积极地在后端进行相应的更新。如果后端更新由于某种原因失败,我们可以通过复制之前的副本来回滚。
  • 但是我使用app.selected = e.model.item 来编辑项目的方式怎么样。这可以吗,还是我现在也应该做一个浅拷贝?能否请您更新我的 JSBin,您将如何实现编辑数组中的项目的整个过程?
猜你喜欢
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
相关资源
最近更新 更多