【问题标题】:polymer 1.0 dom-repeat render not updating dom聚合物 1.0 dom-repeat 渲染不更新 dom
【发布时间】:2016-02-02 08:09:16
【问题描述】:

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

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

【问题讨论】:

    标签: polymer-1.0


    【解决方案1】:

    我正在进行一个庞大的 Polymer 1.9 项目,目前正在切换到 Polymer 2.0,我可以看出在 Polymer 2 中以更好的方式处理了诸如更新 dom-repeat 之类的事情。


    在 dom-repeat 中更新子属性是 1.0 中的噩梦,最简单的解决方案是重写 dirty checks,其中 Polymer 会检查每个属性以查看 DOM 是否需要更新。

    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) 的事情来直接更新子属性,而不是在这里发生的拼接:

        _commitChange: function() {
          // ...
          } else if (this.currChange === 'M') {
            this.splice('data', this.currIndex, 1, this.currItem);
    

    另外,你不需要这个,因为 Polymer 应该会自动更新:

          this.$.listTemplate.render();
    

    【讨论】:

      猜你喜欢
      • 2016-06-26
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      • 2016-04-11
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      • 1970-01-01
      相关资源
      最近更新 更多