Polymer框架中dom-repeat的使用与数据更新机制解析

作者:白露时间:2026-10-29 12:54:36浏览:546

本文介绍Polymer框架中dom-repeat指令的使用,重点解析如何通过items属性遍历数组,并深入探讨Polymer数据更新机制。针对数组动态增删场景,说明原生push无效的原因,并推荐使用Polymer提供的this.push等访问路径操作方法来实现视图同步更新。

Polymer中dom-repeat指令基础

主流前端框架通常都具备将列表数据绑定至DOM的功能,例如Angular使用ng-repeat指令实现该功能。在Polymer中,类似的功能被归类为扩展指令级别。Angular的ng-repeat本质上是一个Directive,而Polymer中的dom-repeat也属于同一层级。在Polymer的设计哲学中,一切皆视为Directive。例如,dom-module用于定义模块,它本身也是一个Directive;而dom-repeat同样如此,但它并非独立的HTML标签,而是基于template标签实现的Directive。其基本使用方式如下:


<script> var Polymer = { dom: 'shadow' }; </script>
<base href="http://www.web-tinker.com/share/" />
<link rel="import" href="polymer/polymer.html" />

<dom-module id="demo-test">
 <template>
  <ul>
   <template is="dom-repeat" items="[[data]]">
    <li>
     第 <strong>[[index]]</strong> 项,
     值为 <strong>[[item]]</strong>
    </li>
   </template>
  </ul>
 </template>
 <script>
  Polymer({
   is: 'demo-test',
   properties: {
    data: {
     type: Array,
     value: [ 'a', 'b', 'c', 'd' ]
    }
   }
  });
 </script>
</dom-module>

<demo-test></demo-test>

dom-repeat数据遍历与更新机制

上述代码通过将template元素的is属性设置为dom-repeat,使得该template内部的内容能够进行循环渲染。循环遍历的依据是template元素上提供的items属性。需要注意的是,items必须是一个数组。尽管这种限制可能在某些场景下略显不便,但它是一种良好的设计实践,有效避免了如Angular中使用for-in遍历数组时可能引发的各类问题。在循环过程中,每一项的索引和值会被分别封装到index和item属性中,供template内部的模板使用,从而输出对应的索引和数值。然而,Polymer的数据更新机制并非基于脏数据检测(dirty checking),因此数据的动态更新可能相对复杂。例如,若有一个按钮,每次点击需要向列表中添加一项,正确的写法应如下所示:


<script> var Polymer = { dom: 'shadow' }; </script>
<base href="http://www.web-tinker.com/share/" />
<link rel="import" href="polymer/polymer.html" />

<dom-module id="demo-test">
 <template>
  <input placeholder="请输入内容" value="{{value::input}}" />
  <button on-click="append">添加一项</button>
  <ul>
   <template is="dom-repeat" items="[[data]]">
    <li>
     第 <strong>[[index]]</strong> 项,
     值为 <strong>[[item]]</strong>
    </li>
   </template>
  </ul>
 </template>
 <script>
  Polymer({
   is: 'demo-test',
   properties: {
    data: {
     type: Array,
     value: [ 'a', 'b', 'c', 'd' ]
    }
   },
   append: function() {
    // data.push(this.value); // 这么写是不行的
    this.push('data', this.value)
   }
  });
 </script>
</dom-module>

<demo-test></demo-test>

前文曾提及,Polymer会将需要监控变化的数据设置为访问器属性。但如果直接修改数组元素,实际上并未对数组对象本身产生任何影响。当将数组赋值给ViewModel(VM)时,Polymer执行的是元素复制操作,而非传递数组对象的引用。这意味着该数组对象并非VM的直接引用,直接对该数组对象进行操作(如调用原生push方法)无法影响VM的状态,因此直接对数组执行push操作是无效的。尽管数组自身的push方法无法操作VM,但Polymer提供了直接操作VM的方法,例如示例中的this.push。该方法的操作对象不是普通对象,而是VM上的一个访问路径(如示例中push的第一个参数'data'即指向VM中的data访问路径)。除了push之外,Polymer还提供了pop、shift等类似原生数组方法的操作(需注意它们并非DOM元素的方法)。虽然这种操作方式略显繁琐,但尚在可接受范围内。

作者最新文章