提问人:Abhigyan Kumar 提问时间:1/24/2023 更新时间:4/4/2023 访问量:58
聚合物,在嵌套数组中添加新项,而不会被 dom-repeat 渲染
Polymer, adding new item in nested Array in not getting rendered by dom-repeat
问:
我有一个嵌套数组,我需要为多个人添加新主题,但为了简单起见,我将仅向 Jon 添加新主题。
[
{
gender: "male",
persons: [
{
name: "Jon",
subjects: [
{ subName: "maths", marks: "45" },
{ subName: "phy", marks: "47" },
],
},
],
},
{
gender: "female",
persons: [
{
name: "Amily",
subjects: [{ subName: "bio", marks: "43" }],
},
],
},
]
我会在按钮点击时添加主题。
addSubject() {
/* This doesn't work */
let newData = [...this.data];
newData[0].persons[0].subjects.push({ subName: "chem", marks: "50" });
this.data = newData;
}
如果我使用,它可以工作,但如果我需要将主题添加到多个人,此方法每次都会更新属性。上面可以累积所有更改的临时数组,只更新一次。this.push("data.0.persons.0.subjects", { subName: "chem", marks: "50" });
呈现
<template is="dom-repeat" items="[[data]]">
<div>Gender: [[item.gender]]</div>
<template is="dom-repeat" items="[[item.persons]]">
<div>Name: [[item.name]]</div>
<template is="dom-repeat" items="[[item.subjects]]">
<div>Subject: [[item.subName]], [[item.marks]]</div>
</template>
</template>
</template>
如果我尝试渲染更简单的数据,那么它可以正常工作
<template is="dom-repeat" items="[[simpleData]]">
<div>Subject: [[item.subName]], [[item.marks]]</div>
</template>
static get properties() {
return {
simpleData: {
type: Array,
notify: true,
value: () => [
{ subName: "math", marks: "11" },
{ subName: "phy", marks: "22" },
],
},
}
addSubjectInSimple() {
let newData = [...this.simpleData];
newData.push({ subName: "chem", marks: "50" });
this.simpleData = newData;
}
答:
尝试在 dom-repeat 上添加 mutable-data
属性。这告诉聚合物在物体变化时随时注意深层变化。(您仍然需要调用或触发 dom 更新。this.set
this.notifyPath
Polymer 非常努力(有时太难了)在它认为不需要更新 dom 时不更新 dom,这就是它对 s 进行脏检查的原因。在创建对象并更改对象时,您使用的是更现代的方法,现代浏览器通常可以处理,但 Polymer 需要“许可”才能使用该方法。dom-repeat
newData
注意:对象扩展是对对象进行浅层复制,而不是深度克隆。(有关更多信息,请参阅此答案。...
评论
mutable-data
dom-repeat
dom-repeat
Polymer.MutableData
dom-repeat
您应该能够对行执行以下操作: .this.data = newData;
this.set("data", newData);
根据 Tanner Stern 的回应,它仍然可能无法更新,即您正在处理浅拷贝,因为它在技术上仍然是同一个对象,并且 Polymer 可能会将其视为未更新。您可以使用以下命令快速克隆阵列:let newData = JSON.parse(JSON.stringify(this.data));
这应该强制 Polymer 将整个数组设置为新值,并通知 dom 它已被更改。通常(根据我过去 5 年的个人经验),Polymer 不喜欢承认任何关于一个孩子访问的通知,例如。obj.obj但不是obj.obj.obj或更深,所以我发现最好的方法是使用 Polymer 函数设置整个数组/对象。set
评论
this.data[0].persons[0].subjects.push({ subName: "chem", marks: "50" }); this.data = [...this.data];