当变量'works'设置为true(以铬为单位)时,以下代码按预期工作,但不是时。我想弄明白为什么。虽然我可以使用工作的,但我应该更好地理解为什么非工作的不起作用。为什么使用this.push一次推送一个数组项并使用this.set设置整个数组之间有什么区别?
'use strict'
var data = [{
id: 1,
children: [{
id: 2
}, {
id: 3,
children: [{
id: 4
}, {
id: 5,
children: [{
id: 6
}, {
id: 7
}]
}, {
id: 8
}]
}, {
id: 9,
children: [{
id: 10,
children: [{
id: 11
}, {
id: 12
}, {
id: 13
}]
}, {
id: 14
}, {
id: 15
}]
}]
}];
class Polymerology2Element extends Polymer.Element {
static get is() {
return 'polymerology2-element';
}
static get properties() {
return {
nodeData: {
type: Array,
value: [],
notify: true
},
node: {
type: null,
value: null,
notify: true
}
};
}
isOdd(num) {
return num % 2;
}
addNodes() {
var works = true;
if (works) {
if (this.node !== null) {
var arr = [];
for (var i = 0; this.node !== undefined &&
this.node !== null && this.node.children !== undefined && i < this.node.children.length; i++) {
arr.push(this.node.children[i]);
}
setTimeout(() => {
this.set('nodeData', arr)
}, 0);
}
} else {
if (this.node !== null) {
for (var i = 0; this.node !== undefined &&
this.node !== null && this.node.children !== undefined && i < this.node.children.length; i++) {
setTimeout(() => {
this.push('nodeData', this.node.children[i])
}, 0);
}
}
}
}
constructor() {
super();
if (Polymerology2Element.instance === undefined) {
this.nodeData = data;
this.node = null;
Polymerology2Element.instance = 0;
} else
Polymerology2Element.instance += 1;
this.instance = Polymerology2Element.instance;
}
connectedCallback() {
super.connectedCallback();
this.addNodes();
}
}
window.customElements.define(Polymerology2Element.is, Polymerology2Element);
:host {
display: block;
}
<base href="https://polygit.org/polymer+polymer+v2.3.1/components/" />
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html" />
<polymerology2-element></polymerology2-element>
<dom-module id="polymerology2-element">
<template>
<ul>
<template is="dom-repeat" items="[[nodeData]]" as="item">
<template is="dom-if" if="{{isOdd(item.id)}}">
<li>Instance: {{instance}}, Node: {{item.id}} (odd)</li>
<polymerology2-element node="[[item]]"></polymerology2-element>
</template>
<template is="dom-if" if="{{!isOdd(item.id)}}">
<li>Instance: {{instance}}, Node: {{item.id}} (even)</li>
<polymerology2-element node="[[item]]"></polymerology2-element>
</template>
</template>
</ul>
</template>
</dom-module>
答案 0 :(得分:0)
这与循环和变量环境如何工作有关 - 而不是与聚合物本身有关。
<强>为什么强>
观察两个选项之间的以下差异:
works
循环中),setTimeOut
在循环外被调用。setTimeOut
位于循环内部。
这意味着当您进行所有push
次调用时(由于您选择了0超时,就在调用堆栈的末尾),您的for
循环已经完成。 i
已递增并等于this.node.children.length + 1
。 (+ 1
是因为在达到this.node.children.length
后,由于i
,您的i++
将再次递增。这就是为什么你得不到你期望的东西:你实际上已经多次this.push('nodeData', this.node.children[
this.node.children.length + 1 ])
。 如何修复
我知道你已经有了一个工作选项,并没有真正寻找你的this.push
选项的修复 - 但是如果你将来遇到类似的情况,通常可以做到这一点:你需要创建一个在setTimeOut
周围关闭,以便在调用回调时记住i
的值。
试试这个:
for (var i = 0; /* ... your conditions */; i++) {
(function(j) {
setTimeout(() => {
this.push('nodeData', this.node.children[j])
}, 0);
})(i);
}