聚合物-更新元素



我正在学习聚合物。一个挑战我的项目是更新数组的项目。我希望有一个聚合物CDN,这样我就可以把小提琴放在一起了。不过现在,我有一个定义如下的元素:

my element.html

<dom-module id="my-element">
  <button on-click="onLoadData">Load Data</button>  
  <button on-click="onTest1Click">Test 1</button>
  <button on-click="onTest2Click">Test 2</button>
  <template is="dom-repeat" items="[[ data ]]" as="element">
    <div><span>[[ element.id ]]</span> - <span>[[ element.status ]]</span></div>
    <template is="dom-repeat" items="[[ element.children ]]" as="child">
      <div>&nbsp;&nbsp;<span>[[ child.id ]]</span> - <span>[[ child.status ]]</span></div>
    </template>
  </template>
  </template>
  <script>
    Polymer({
      is: 'my-element',
      properties: {
        data: {
          type: Array,
          value: function() {
            return [];
          }
        }
      },
      onLoadData: function() {
        // Generate some dummy data for the sake of illustration.
        for (var i=1; i<=3; i++) {
          var element = {
            id: i,
            state: 'Initialized',
            description: ''
          };
          element.children = [];
          for (var j=1; j<=5; j++) {
            var child = {
              id: i + '-' + j,
              state: 'Initialized',
              description: ''
            }
            element.children.push(child);
          }
          data.push(element);
        }
      },
      // Setting an individual property value works
      onTest1Click: function() {
        this.set('data.0.children.0.state', 'data set');
      },
      // Setting an entire object value does NOT work.
      onTest2Click: function() {
        var c = this.data[0].children[0];
        c.state = 'data set';
        this.set('data.0.children.0', c);
      }
    });
  </script>
</dom-module>

出于某种原因,如果我更新数组元素的属性值(如onTest1Click所示),则UI将正确更新。但是,如果我更新整个元素(如onTest2Click所示),则UI不会得到更新。在我的实际问题中,我正在更新一个元素的多个属性。因此,我尝试更新数组元素,而不仅仅是属性。我是做错了什么还是误解了什么?或者,我是否必须单独更新每个属性值?

如果您想突变数组,而不仅仅是数组中的一个对象(例如交换掉数组中的整个元素),有类似于this.set的数组突变方法。

例如,this.splice('data.0.children', 0, 1, c)将删除子数组0索引处的当前项,并将其替换为新项,这似乎是您正在尝试执行的操作。还有this.shiftthis.unshiftthis.pushthis.pop。这些都与它们的Array原型相似。

需要注意的一点是,在您的示例中,您实际上也没有交换出整个对象。当您从数组中获取元素,对字段进行变异,并尝试将其替换为自身时,实际上并不是在替换它,因此这实际上不会触发更新。由于该字段的突变是在Polymer的通知系统之外进行的,因此也不会触发更新。如果将项目替换为实际的不同对象,它将使用拼接工作。https://jsbin.com/rapomiyaga/1/edit?html,输出(这是Günter Zöchbauer的jsbin的修改快照)

如果您没有复制对象/创建一个全新的对象,则需要通过this.set单独更新每个字段。

是的,您需要单独更新每个属性值。当您调用set时,Polymer将转到给定的路径并检查该值是否已更改。如果值是一个对象,它将比较引用(而不是子属性)。由于对象引用没有更改,因此不会更新UI。

最新更新