我有一个dom-repeat
和另一个dom-repeat
嵌套在里面。外部绑定到计算数组。当我对父数组进行更改时,会观察到更改(意味着会触发观察者代码),但更改不会反映在UI / dom-repeat
中。
以下是我的代码示例。单击第二个div
内的dom-repeat
触发函数handleItemTap
,然后对父数组进行更改。然后观察这种变化,重新计算计算出的数组;但是,将IsChecked
添加到父对象不会影响UI中的复选框,该复选框应该绑定到IsChecked
属性。我做错了什么?
<template is="dom-repeat"
items="[[outerComputedArray]]" as="group"
id="groupRepeater">
<div class="group-container">
<template is="dom-repeat"
items="[[group.InnerArray]]" as="sesh">
<div on-tap="handleItemTap">
<paper-checkbox id="paperCheckboxId"
checked="[[sesh.IsChecked]]"></paper-checkbox>
</div>
</template>
</div>
</template>
...
static get properties() {
return {
'parentArray': Array,
'outerComputedArray': {
type: Array,
computed: 'computeOuterArray(parentArray.*)'
}
}
}
computeOuterArray(parentArray) {
if (!(typeof parentArray.base === 'undefined' || parentArray.base == null || parentArray.base.length == 0)) {
let groupedGrid = parentArray.base.reduce((a, b) => {
a = a || [];
let idx = a.findIndex(x => x.PaymentType == b.PaymentType);
if (idx == -1) {
let newArray = [];
newArray.push(b);
a.push({ 'PaymentType': b.PaymentType, 'InnerArray': newArray });
}
else {
a[idx].InnerArray.push(b);
}
return a;
}, []).map(x => {
x.Total = x.InnerArray.map(y => y.TotalAmount).reduce((a, b) => a + b, 0);
return x;
});
groupedGrid.sort((a, b) => a.PaymentType.localeCompare(b.PaymentType));
return groupedGrid;
}
return [];
}
handleItemTap(e) {
let idx = this.parentArray.findIndex(x => x.id == e.model.sesh.id);
this.set(`parentArray.${idx}.IsChecked`, !(!!e.model.sesh.IsChecked));
}
答案 0 :(得分:0)
看起来像Polymer对象脏检查是这里的问题。它用于加速Polymer,但有时脏检查不起作用(例如,当您更改数组中的元素时)。 要绕过它,您需要使用mutable data mixin。
首先,您需要在声明元素时引入mixin。
class MyMutableElement extends Polymer.MutableData(Polymer.Element) { ... }
您还需要将mutable-data标志添加到dom-repeat。
<template is="dom-repeat" items="[[outerComputedArray]]" as="group" id="groupRepeater" mutable-data>
如果它仍然不起作用,请尝试在computeOuterArray函数的末尾添加这样的内容(但仅当您实际更改数组时)。
timeout(() => { this.notifyPath('outerComputedArray') }, 10)
答案 1 :(得分:0)
我非常感谢@ mary-shaw试图提供帮助,但我无法将这些建议付诸实施。这就是我现在提出的问题。我已经在outerComputedArray
上放置一个观察者来更新第二个数组 - 一个名为selectedIds
的新属性 - 包含已更改属性IsChecked
的所有项目。然后,我添加了另一个计算函数,用于检查selectedIds
是否与最里面的id
中的对象具有相同的dom-repeat
属性。
<template is="dom-repeat"
items="[[outerComputedArray]]" as="group">
<div class="group-container">
<template is="dom-repeat"
items="[[group.InnerArray]]" as="sesh">
<div on-tap="handleItemTap">
<paper-checkbox id="paperCheckboxId"
checked="[[computeIsChecked(selectedIds.*, sesh.id)]]"></paper-checkbox>
</div>
</template>
</div>
</template>
...
<script>
static get properties() {
return {
'parentArray': Array,
'outerComputedArray': {
type: Array,
computed: 'computeOuterArray(parentArray.*)'
},
'selectedIds': Array
}
}
static get observers() {
return [
'onOuterComputedArrayChanged(outerComputedArray.*)'
]
}
onOuterComputedArrayChanged(outerComputedArray) {
if (!(typeof outerComputedArray.base === 'undefined' || outerComputedArray.base == null || outerComputedArray.base.length == 0)) {
this.set('selectedIds', outerComputedArray.base.filter(x => x.InnerArray.some(y => !!y.IsChecked)).map(x => x.InnerArray.filter(y => !!y.IsChecked)).reduce((a, b) => a.concat(b), []).map(x => x.id));
}
}
computeIsChecked(selectedIds, id) {
if (!(typeof selectedIds.base === 'undefined' || selectedIds.base == null || selectedIds.base.length == 0)) {
return selectedIds.base.some(x => x == id);
}
return !!0;
}
computeOuterArray(parentArray) {
if (!(typeof parentArray.base === 'undefined' || parentArray.base == null || parentArray.base.length == 0)) {
let groupedGrid = parentArray.base.reduce((a, b) => {
a = a || [];
let idx = a.findIndex(x => x.PaymentType == b.PaymentType);
if (idx == -1) {
let newArray = [];
newArray.push(b);
a.push({ 'PaymentType': b.PaymentType, 'InnerArray': newArray });
}
else {
a[idx].InnerArray.push(b);
}
return a;
}, []).map(x => {
x.Total = x.InnerArray.map(y => y.TotalAmount).reduce((a, b) => a + b, 0);
return x;
});
groupedGrid.sort((a, b) => a.PaymentType.localeCompare(b.PaymentType));
return groupedGrid;
}
return [];
}
handleItemTap(e) {
let idx = this.parentArray.findIndex(x => x.id == e.model.sesh.id);
this.set(`parentArray.${idx}.IsChecked`, !(!!e.model.sesh.IsChecked));
}
</script>