Polymer绑定如何在数组上起作用?

时间:2016-08-25 09:43:01

标签: arrays data-binding polymer web-component

让我们考虑以下代码:

  <dom-module id="foo-bar">
  <template>
    <h2>Example 1</h2>
    <button on-tap="tap1">Tap 1</button> | <button on-tap="tap2">Tap 2</button> 
    <hr>
    <ul>
      <template is="dom-repeat" items="{{myarray}}">
        <li>{{index}}: {{item.title}}</li>
      </template>
    </ul>
    <hr>
    {{myarray}}
    <hr>
    <h2>Example 1</h2>
    <button on-tap="tap3">Tap 3</button>
    <hr>
    <ul>
      <template is="dom-repeat" items="{{myarray2}}">
        <li>{{index}}: {{item.title}}</li>
      </template>
    </ul>
    <hr>
    {{myarray2}}
    <hr>
  </template>
  <script>
    Polymer({
      is: 'foo-bar',
      properties: {
        myarray: {
          type: Array,
          value: [null, null],
          notify: true
        },
        myarray2: {
          type: Array,
          value: [{title: 'a'}, {title: 'b'}],
          notify: true
        }
      },
      tap1: function() {
        this.myarray = [{title: 'Hello'}, {title: 'World'}];
      },
      tap2: function() {
        this.set('myarray.0', {title: 'Hello'});
        this.set('myarray.1', {title: 'World'});
      },
      tap3: function() {
        this.set('myarray2.0', {title: 'Hello'});
        this.set('myarray2.1', {title: 'World'});
      }
    })
  </script>
</dom-module>

原则是显示数组的内容(myarray),并在内容发生变化时更新显示内容。

当我点击Tap 1按钮时,由于数组已完全重新定义,所以一切都按预期工作。

根据documentation,Polymer无法检测数组本身的修改,他们建议使用this.set(...)方法。这就是我在代码的tap2函数中所做的:

  tap2: function() {
    this.set('myarray.0', {title: 'Hello'});
    this.set('myarray.1', {title: 'World'});
  }

但是,当我点击Tap 2按钮时,即使代码中的数组已正确更新(我可以使用console.log看到它),列表也会显示(<ul></ul>} )没有正确设置,因为我得到:

  
      
  • 0:世界
  •   
  • 1:
  •   

(第一个索引显示aray的第二个元素的值)并且数组的完整显示(在{{myarray}}中)不会打印任何内容。

另一种情况Tap3,行为正确,因为我已经直接用对象初始化了一个数组(myarray2)。

我还做了另一个测试(不是在Plunker上),其中myarray初始化为[](而不是[null, null])。在这种情况下,列表(<ul></ul>)在单击按钮之前或之后始终为空。

最后,我的问题是要了解双重绑定如何对数组内容起作用,以及为什么第二种情况(Tap 2)会发生?

由于

Plunker link

1 个答案:

答案 0 :(得分:1)

问题是dom-repeat在非唯一原语方面存在问题(请参阅此issue)。元素需要具有唯一的身份。作为一种解决方法,您可以像这样定义数组:

myarray: {
  type: Array,
  value: function() { return [{}, {}];},
  notify: true
},

这将解决问题(请参阅修改后的plunker

作为旁注:对于ArraysObject属性,请确保使用function返回默认value,否则您将遇到问题(基本上共享该元素的所有实例中的值)