聚合物1.0 dom-repeat渲染不更新dom

时间:2016-02-02 08:09:16

标签: polymer-1.0

我有一个使用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>

我在大多数例子中看到的字符串。

1 个答案:

答案 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();

希望这会有所帮助。