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-ifdom-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>