我正在学习聚合物。一个挑战我的项目是更新数组的项目。我希望有一个聚合物的CDN,所以我可以把小提琴放在一起。现在,我有一个像这样定义的元素:
我-element.html
<dom-module id="my-element">
<button on-click="onLoadData">Load Data</button>
<button on-click="onTest1Click">Test 1</button>
<button on-click="onTest2Click">Test 2</button>
<template is="dom-repeat" items="[[ data ]]" as="element">
<div><span>[[ element.id ]]</span> - <span>[[ element.status ]]</span></div>
<template is="dom-repeat" items="[[ element.children ]]" as="child">
<div> <span>[[ child.id ]]</span> - <span>[[ child.status ]]</span></div>
</template>
</template>
</template>
<script>
Polymer({
is: 'my-element',
properties: {
data: {
type: Array,
value: function() {
return [];
}
}
},
onLoadData: function() {
// Generate some dummy data for the sake of illustration.
for (var i=1; i<=3; i++) {
var element = {
id: i,
state: 'Initialized',
description: ''
};
element.children = [];
for (var j=1; j<=5; j++) {
var child = {
id: i + '-' + j,
state: 'Initialized',
description: ''
}
element.children.push(child);
}
data.push(element);
}
},
// Setting an individual property value works
onTest1Click: function() {
this.set('data.0.children.0.state', 'data set');
},
// Setting an entire object value does NOT work.
onTest2Click: function() {
var c = this.data[0].children[0];
c.state = 'data set';
this.set('data.0.children.0', c);
}
});
</script>
</dom-module>
出于某种原因,如果我更新数组元素的属性值(如onTest1Click
所示),则UI会正确更新。但是,如果我更新整个元素(如onTest2Click
所示),则UI不会更新。在我真正的问题中,我正在更新元素的多个属性。出于这个原因,我试图更新数组元素而不仅仅是属性。我做错了什么或误解了什么?或者,我是否必须单独更新每个属性值?
答案 0 :(得分:1)
如果你想改变一个数组,而不仅仅是一个数组中的一个对象(比如交换一个数组中的整个元素),那么有一些类似于this.set
的数组变异方法。
例如,this.splice('data.0.children', 0, 1, c)
将删除子数组0索引处的当前项,并将其替换为新项,这就是您尝试执行的操作。还有this.shift
,this.unshift
,this.push
和this.pop
。这些都与他们的Array原型相似。
需要注意的一点是,在您的示例中,您实际上并没有交换整个对象。当你从数组中获取元素时,改变一个字段,并尝试用它自己替换它,你实际上并没有替换它,所以实际上并没有触发更新。由于该字段的变异是在Polymer的通知系统之外完成的,因此也不会触发更新。如果用实际的不同对象替换项目,它将使用拼接工作。 https://jsbin.com/rapomiyaga/1/edit?html,output(这是GünterZöchbauer的jsbin的修改快照)
如果您没有复制对象/一个全新的对象,则需要通过this.set
单独更新每个字段。
答案 1 :(得分:0)
是的,您需要单独更新每个属性值。当您调用set
时,Polymer将转到给定路径并检查值是否已更改。如果值是一个对象,它将比较引用(而不是子属性)。由于对象引用未更改,因此不会更新UI。