我有一个使用dom-repeat渲染对象数组的元素。还有一个功能可以修改特定对象。但是,在更新对象后,即使更新了数组,dom也不会反映更改(也会调用render)。我正在使用Polymer提供的变异函数(this.slice,看看下面的_commitChange函数)。有人能指出这里有什么问题吗? 需要注意的一点是,数组中的单个项是对象而不是基元/
<dom-module id="em-person-qualifications">
<template>
<style include="shared-styles"></style>
<style>
:host {
display: block;
}
iron-pages {
height: 100%;
}
</style>
<iron-pages id="container" selected="0">
<div id="listContainer">
<template id="listTemplate" is="dom-repeat" items="[[data]]">
<paper-item>
<paper-item-body two-line>
<div>
<span>[[item.qualificationLevel.level]]</span>,
<span>[[item.qualificationLevel.levelCategory]]</span>
</div>
<div secondary>
<span>[[item.fromInstitute.edumateOrgDisplayName]]</span>
<span>[[item.status]]</span>
</div>
</paper-item-body>
<paper-icon-button icon="more-vert" on-tap="_loadModifyUI"></paper-icon-button>
</paper-item>
</template>
</div>
<div id="detailContainer">
<paper-toolbar>
<div class="title">
<us-com-i18n key="qualificationDetail"></us-com-i18n>
</div>
<paper-icon-button id="button" icon="clear" on-click="_showList"></paper-icon-button>
</paper-toolbar>
<div>
<iron-label for="levelContainer">
<us-com-i18n key="level"></us-com-i18n>
</iron-label>
<div id="levelContainer" class="layout horizontal wrap">
<us-com-freeorref data="{{currItem.qualificationLevel.level}}"></us-com-freeorref>
<paper-dropdown-menu label="select">
<paper-menu class="dropdown-content" attrForSelected="data-value" selected="{{currItem.qualificationLevel.levelCategory}}">
<paper-item data-value="10">Graduate</paper-item>
<paper-item data-value="11">Post-graduate</paper-item>
</paper-menu>
</paper-dropdown-menu>
</div>
<iron-label for="majorSubjectContainer">
<us-com-i18n key="majors"></us-com-i18n>
</iron-label>
<div id="majorSubjectContainer">
<template is="dom-repeat" items="[[currItem.majorSubjects]]">
<em-party-subject data="{{item}}"></em-party-subject>
</template>
</div>
<iron-label for="minorSubjectContainer">
<us-com-i18n key="minors"></us-com-i18n>
</iron-label>
<div id="minorSubjectContainer">
<template is="dom-repeat" items="[[currItem.minorSubjects]]">
<em-party-subject data="{{item}}"></em-party-subject>
</template>
</div>
<iron-label for="during">
<us-com-i18n key="during"></us-com-i18n>
</iron-label>
<div class="layout horizontal wrap" id="during">
<span><us-com-i18n key="from"></span>
<us-com-date data="{{currItem.fromMonthYear}}"></us-com-date>
<span><us-com-i18n key="to"></span>
<us-com-date data="{{currItem.toMonthYear}}"></us-com-date>
</div>
<paper-input type="text" value="{{currItem.status}}" label="status">
<us-com-formattedlongtext data="{{currItem.achievmentStatement}}" label="achievements"></us-com-formattedlongtext>
<div class="buttons">
<paper-button tabindex="0" raised autofocus on-click="_commitChange">
<iron-icon icon="check"></iron-icon>Ok
</paper-button>
</div>
</div>
</div>
</iron-pages>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'em-person-qualifications',
properties: {
data: {
type: Array,
value: function() {
return [{
'qualificationLevel': {
'level': 'Bsc',
'levelCategory': 10
},
'majorSubjects': [],
'minorSubjects': [],
'fromMonthYear': {},
'toMonthYear': {},
'fromInstitute': {
'edumateOrgDisplayName': 'XYZ College'
},
'status': 'ABCD',
'achievmentStatement': {}
}, {
'qualificationLevel': {
'level': 'M-Tech',
'levelCategory': 11
},
'majorSubjects': [],
'minorSubjects': [],
'fromMonthYear': {},
'toMonthYear': {},
'fromInstitute': {
'edumateOrgDisplayName': 'ABC College'
},
'status': 'EFGH',
'achievmentStatement': {}
}];
}
},
currItem: Object,
currIndex: Number,
currChange: String
},
behaviors: [app.I18nBehavior],
_showList: function() {
this._commitChange();
//this.$.container.selected = '0';
},
_loadAddUI: function() {
this.currChange = 'A';
this.currItem = {};
this.$.container.selected = '1';
},
_loadModifyUI: function(e) {
this.currChange = 'M';
this.currItem = e.model.item;
this.currIndex = this.data.indexOf(e.model.item);
this.$.container.selected = '1';
},
_loadDeleteUI: function() {
this.currChange = 'D';
//Find out the index from the data-index attribute of the button
this.currIndex = 0;
},
_commitChange: function() {
//var model = e.model;
//this.splice('data',)
if (this.currChange === 'A') {
this.push('data', this.currItem);
} else if (this.currChange === 'M') {
this.splice('data', this.currIndex, 1, this.currItem);
console.log('data[this.currIndex] = ' + this.data[this.currIndex].status);
} else if (this.currChange === 'D') {
this.splice('data', this.currIndex, 1);
}
this.$.listTemplate.render();
this.$.container.selected = '0';
}
});
})();
</script>
</dom-module>
我在大多数例子中看到的字符串。
答案 0 :(得分:1)
我正在处理一个庞大的Polymer 1.9项目,目前正在切换到Polymer 2.0,我可以说在Polymer 2中可以更好地处理更新dom-repeat之类的事情。
在dom-repeat中更新子属性在1.0中是一场噩梦,最简单的解决方案是覆盖脏检查,其中Polymer会检查每个属性以查看DOM是否需要更新。 / p>
var copiedData = JSON.parse( JSON.stringify(data) );
this.set('data', []);
this.set('data', copiedData);
如果您不顾一切,请使用此方法,但如果手机上的列表超过100个,它可能会导致性能问题。您可能也可以做...
this.set('data', JSON.parse( JSON.stringify(data) ));
...作为一个全新的数组将覆盖脏检查。无论如何,如果数组的长度不变,dom-repeat不会用this.splice
更新,所以我会做类似this.set('data.' + this.currIndex, this.currItem)
的操作来直接更新子属性,而不是在这里进行拼接:< / p>
_commitChange: function() {
// ...
} else if (this.currChange === 'M') {
this.splice('data', this.currIndex, 1, this.currItem);
此外,您也不需要它,因为Polymer应该会自动更新:
this.$.listTemplate.render();
希望这会有所帮助。