聚合物 - 更新元素

时间:2015-12-09 15:09:58

标签: polymer

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

我-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不会更新。在我真正的问题中,我正在更新元素的多个属性。出于这个原因,我试图更新数组元素而不仅仅是属性。我做错了什么或误解了什么?或者,我是否必须单独更新每个属性值?

2 个答案:

答案 0 :(得分:1)

如果你想改变一个数组,而不仅仅是一个数组中的一个对象(比如交换一个数组中的整个元素),那么有一些类似于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,output(这是GünterZöchbauer的jsbin的修改快照)

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

答案 1 :(得分:0)

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