dom-repeat 内的函数调用只执行一次
functions calls inside dom-repeat only executed once
我们无法得到这个简单的用例运行 polymer@1.4.0。我们有一个项目列表。如果用户单击某个项目,则会在该项目之前显示一个图标。还将向此项添加特定的 is-selected
class。
列表将以 dom 重复呈现。每个列表项如下所示:
{
"label": "Item 1",
"value": 0
}
如果用户单击该项目,我们会将值存储在变量 selectedValue
中。出于某种原因,dom-repeat 不会重新渲染。因此最初只会调用函数 isSelected 和 getSelectedClass。但不是在点击交互之后。我们已经尝试在 selectItem 函数中使用 this.$.listItems.render();
。而且还要有效果。我们该如何处理?
我们当前的代码:
<dom-module id="selectable-list">
<template>
<style is="custom-style" include="selectable-list-styles"></style>
<ul id="selectable-list">
<template is="dom-repeat" items="[[items]]" id="itemList">
<li class$="{{getSelectedClass(item)}}">
<template is="dom-if" if="{{isSelected(item)}}">
<iron-icon icon="sanitas-icons:check"></iron-icon>
</template>
<button type="button" on-click="selectItem">{{item.label}}</button>
</li>
</template>
</ul>
</template>
<script>
var SELECTED_CLASS = 'is-selected';
Polymer({
is: 'selectable-list',
properties: {
items: {
type: Array,
value: []
},
selectedValue: {
type: Object,
notify: true,
reflectToAttribute: true
}
},
selectItem: function(event){
this.selectedValue = event.model.item.value;
},
/**
* check if a list item is selected
*
* @param {object} item
* @returns {boolean}
*/
isSelected: function(item){
return item.value === this.selectedValue;
},
/**
* get selected class if item is selected
* @param {object} item
* @returns {string}
*/
getSelectedClass: function(item){
return this.isSelected(item) ? SELECTED_CLASS : '';
}
});
</script>
</dom-module>
问题是你的 dom-if
和 dom-repeat
一旦你 select 一些项目就不会被重新触发,因为它们都依赖于 item
而不会改变.因此,简单的解决方案是将 selectedValue
也作为变量添加到您的函数
<li class$="{{getSelectedClass(item, selectedValue)}}">
<template is="dom-if" if="{{isSelected(item,selectedValue)}}">
在 js 中
isSelected: function(item, selectedValue){
return item.value === selectedValue;
},
getSelectedClass: function(item, selectedValue){
return this.isSelected(item, selectedValue) ? SELECTED_CLASS : '';
}
<base href="https://polygit.org/polymer+v1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<dom-module id="selectable-list">
<template>
<style is="custom-style" include="selectable-list-styles"></style>
<ul id="selectable-list">
<template is="dom-repeat" items="[[items]]" id="itemList">
<li class$="{{getSelectedClass(item, selectedValue)}}">
<template is="dom-if" if="{{isSelected(item,selectedValue)}}">
yes
</template>
<button type="button" on-click="selectItem">{{item.label}}</button>
</li>
</template>
</ul>
</template>
<script>
var SELECTED_CLASS = 'is-selected';
Polymer({
is: 'selectable-list',
properties: {
items: {
type: Array,
value: function() {
return [{
"label": "Item 1",
"value": 0
}, {
"label": "Item 2",
"value": 1
}, {
"label": "Item 3",
"value": 2
}]
}
},
selectedValue: {
type: Object,
notify: true,
reflectToAttribute: true
}
},
selectItem: function(event) {
this.selectedValue = event.model.item.value;
},
/**
* check if a list item is selected
*
* @param {object} item
* @returns {boolean}
*/
isSelected: function(item, selectedValue) {
return item.value === selectedValue;
},
/**
* get selected class if item is selected
* @param {object} item
* @returns {string}
*/
getSelectedClass: function(item, selectedValue) {
return this.isSelected(item, selectedValue) ? SELECTED_CLASS : '';
}
});
</script>
</dom-module>
<selectable-list></selectable-list>
我们无法得到这个简单的用例运行 polymer@1.4.0。我们有一个项目列表。如果用户单击某个项目,则会在该项目之前显示一个图标。还将向此项添加特定的 is-selected
class。
列表将以 dom 重复呈现。每个列表项如下所示:
{
"label": "Item 1",
"value": 0
}
如果用户单击该项目,我们会将值存储在变量 selectedValue
中。出于某种原因,dom-repeat 不会重新渲染。因此最初只会调用函数 isSelected 和 getSelectedClass。但不是在点击交互之后。我们已经尝试在 selectItem 函数中使用 this.$.listItems.render();
。而且还要有效果。我们该如何处理?
我们当前的代码:
<dom-module id="selectable-list">
<template>
<style is="custom-style" include="selectable-list-styles"></style>
<ul id="selectable-list">
<template is="dom-repeat" items="[[items]]" id="itemList">
<li class$="{{getSelectedClass(item)}}">
<template is="dom-if" if="{{isSelected(item)}}">
<iron-icon icon="sanitas-icons:check"></iron-icon>
</template>
<button type="button" on-click="selectItem">{{item.label}}</button>
</li>
</template>
</ul>
</template>
<script>
var SELECTED_CLASS = 'is-selected';
Polymer({
is: 'selectable-list',
properties: {
items: {
type: Array,
value: []
},
selectedValue: {
type: Object,
notify: true,
reflectToAttribute: true
}
},
selectItem: function(event){
this.selectedValue = event.model.item.value;
},
/**
* check if a list item is selected
*
* @param {object} item
* @returns {boolean}
*/
isSelected: function(item){
return item.value === this.selectedValue;
},
/**
* get selected class if item is selected
* @param {object} item
* @returns {string}
*/
getSelectedClass: function(item){
return this.isSelected(item) ? SELECTED_CLASS : '';
}
});
</script>
</dom-module>
问题是你的 dom-if
和 dom-repeat
一旦你 select 一些项目就不会被重新触发,因为它们都依赖于 item
而不会改变.因此,简单的解决方案是将 selectedValue
也作为变量添加到您的函数
<li class$="{{getSelectedClass(item, selectedValue)}}">
<template is="dom-if" if="{{isSelected(item,selectedValue)}}">
在 js 中
isSelected: function(item, selectedValue){
return item.value === selectedValue;
},
getSelectedClass: function(item, selectedValue){
return this.isSelected(item, selectedValue) ? SELECTED_CLASS : '';
}
<base href="https://polygit.org/polymer+v1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<dom-module id="selectable-list">
<template>
<style is="custom-style" include="selectable-list-styles"></style>
<ul id="selectable-list">
<template is="dom-repeat" items="[[items]]" id="itemList">
<li class$="{{getSelectedClass(item, selectedValue)}}">
<template is="dom-if" if="{{isSelected(item,selectedValue)}}">
yes
</template>
<button type="button" on-click="selectItem">{{item.label}}</button>
</li>
</template>
</ul>
</template>
<script>
var SELECTED_CLASS = 'is-selected';
Polymer({
is: 'selectable-list',
properties: {
items: {
type: Array,
value: function() {
return [{
"label": "Item 1",
"value": 0
}, {
"label": "Item 2",
"value": 1
}, {
"label": "Item 3",
"value": 2
}]
}
},
selectedValue: {
type: Object,
notify: true,
reflectToAttribute: true
}
},
selectItem: function(event) {
this.selectedValue = event.model.item.value;
},
/**
* check if a list item is selected
*
* @param {object} item
* @returns {boolean}
*/
isSelected: function(item, selectedValue) {
return item.value === selectedValue;
},
/**
* get selected class if item is selected
* @param {object} item
* @returns {string}
*/
getSelectedClass: function(item, selectedValue) {
return this.isSelected(item, selectedValue) ? SELECTED_CLASS : '';
}
});
</script>
</dom-module>
<selectable-list></selectable-list>