— Polymer — 3 min read
Polymer提供一系列的自定义元素来简化一些共有的数据绑定逻辑:
dom-repeat 遍历显示数组array-selector 数组选择器dom-if 条件显示dom-bind 自动绑定2.0 tip. The data binding helper elements are bundled in to the backward-compatible,
polymer.htmlimport. If you aren't using the legacy import, you'll need to import the helper elements you're using.
为了向前兼容,polymer.html引入了所有的helper元素,而2.0的polymer.Element则要按照需要一个个手动引入。
dom-repeat需要绑定一个数组,遍历显示里面元素,并为每个数组元素创建一个新的data scope,包括下面两个属性:
item 数组元素index 元素下标有两种用法:
<dom-repeat>标签在这种情况下,还需要手动使用js给<dom-repeat>标签设置数据:需要使用可被监听的手段去更改dom-repeat绑定的数组
dom-repeat templates {#handling-events}When handling events generated by a
dom-repeattemplate instance, you frequently want to map the element firing the event to the model data that generated that item.
When you add a declarative event handler inside the
<dom-repeat>template, the repeater adds amodelproperty to each event sent to the listener. Themodelobject contains the scope data used to generate the template instance, so the item data ismodel.item:
当你帮定义一个事件到dom-repeat的内部元素之后,事件参数e会有一个model项,代表着当前元素的data scope.
The
modelis an instance ofTemplateInstance, which provides the Polymer data APIs:get,set,setProperties,notifyPathand the array manipulation methods. You can use these to manipulate the model, using paths relative to template instance.
model也是一个TemplateInstance的子类,提供了get,set,setProperties,notifyPath等data API
只有在dom-repeat里面绑定过的属性才会赋给model,如下面例子,将productId绑定到不可见的自定义属性上,以便将productId添加到model对象中。
dom-repeat template.The
modelproperty is not added for event listeners registered imperatively (usingaddEventListener), or listeners added to one of thedom-repeattemplate's parent nodes. In these cases, you can use thedom-repeatmodelForElementmethod to retrieve the model data that generated a given element. (There are also correspondingitemForElementandindexForElementmethods.) 外部如果使用标准的DOM APIaddEventListener来监听子元素的事件时,则事件参数里面没有e.model属性,可以使用下面几个函数手动获得:
dom-repeat.modelForElementdom-repeat.itemForElementdom-repeat.indexForElementTo filter or sort the displayed items in your list, specify a
filterorsortproperty on thedom-repeat(or both): 可以在dom-repeat上指定filter或sort的方法。
默认,filter和sort方法只在两种情况下被调用:
使用render方法强制filter和sort方法重新执行。(见Forcing synchronous renders)
To re-run the
filterorsortfunctions when certain sub-fields ofitemschange, set theobserveproperty to a space-separated list ofitemsub-fields that should cause the list to be re-filtered or re-sorted.
如果filter/sort是依据数组元素的某一个子属性来排序的,需要在dom-repeat标签上设置一个observe属性,将过滤或排序依据的子属性按照空格连接起来的字符设为它的值。
比如,下面这个例子,设置一个叫isEngineer的filter:
在dom-repeat标签上设置过滤器所使用过的元素子属性type manager.type
修改第0个元素中的manager.type将会导致整个列表重新过滤
observe属性并不能完全解决所有需求,也许filter/sort函数需要用到其他地方的变量,因此我们可以实现一个computed binding来动态返回一个filter/sort函数
Because of the way Polymer tracks arrays internally, the array index isn't passed to the filter function. Looking up the array index for an item is an O(n) operation. Doing so in a filter function could have significant performance impact.
不能获得数组索引,只能通过this.items获得原来数组,再通过indexOf方法获得索引,效率低下。
注意,filter/sort方法中,不是数组元素所创建的子data scope
When nesting multiple
dom-repeattemplates, you may want to access data from a parent scope. Inside adom-repeat, you can access any properties available to the parent scope unless they're hidden by a property in the current scope. 比如类继承一样,子scope中可以取父scope的所有没有被覆盖的属性。
To access properties from nested
dom-repeattemplates, use theasattribute to assign a different name for the item property. Use theindex-asattribute to assign a different name for the index property. 可以使用as标记来对默认的item来重命名 可以使用index-as标记来对默认的index来重命名
默认的dom-repeat是异步执行的,但是可以调用render方法使之立即同步渲染。
此方法性能代价比较大,适用于下面几种情况:
sort/filter方法需要重新运行注意: render方法只会更新模型数据的Observable change,如果要全局更新见下一节。
强制刷新列表元素,像之前所说过的三种解决方案:
notifySplices,如果你知道数组的具体变更方式mutableData标签再this.notifyPath(items)当列表数据量很大的时候,dom-repeat支持延迟加载。设置initialCount属性,可以启动chunked mode,dom-repeat首先会渲染initialCount个元素,然后按照一个animation frame一chunk的形式渲染其他元素,这样能够让UI在渲染的过程中处理用户的输入。可以查看renderedItemCount属性(只读)来获得当前已被渲染的元素总数。
dom-repeatadjusts the number of items rendered in each chunk to try and maintain a target framerate. You can further tune rendering by setting targetFramerate.
dom-repeat尝试去维护一个targetFramerate函数来调整每一个渲染的chunk里面的元素个数,具体:targetFramerate
Keeping structured data in sync requires that Polymer understand the path associations of data being bound. The
array-selectorelement ensures path linkage when selecting specific items from an array.
array-selector 可以选择数组里面的元素,并自动把选择出来的元素的路径跟这些元素的原来路径进行连接。(linkPaths)
items属性接收一个数组。select(item)\deselect(item)multi属性可以开关多选dom-if 可以按条件来显示其中的内容。最开始的时候dom-if中没有元素,当把if属性设置为true时里面就会出现template中的的元素,当if属性再次变为false时,其内部元素默认不会被删除,而是直接隐藏。可以设置restamp为true来禁止这种隐藏行为。
跟dom-if一样,有两种方式来定义:
在Polymer element template内部,使用简写方式
在Polymer element template外部,使用<dom-if>标签
这种情况需要手动设置dom-if的属性:
代码实例:
Conditional templates introduce some overhead, so they shouldn't be used for small UI elements that could be easily shown and hidden using CSS.
条件模板会引入一些开销,因此不适合一些可以直接设置CSS来控制显示和隐藏的小元素。 但是条件模板也适用于下面几种情况:
restam=true会带来性能上的损失)Polymer data binding is only available in templates that are managed by Polymer. So data binding works inside an element's DOM template (or inside a
dom-repeatordom-iftemplate), but not for elements placed in the main document.
To use Polymer bindings without defining a new custom element, use the
<dom-bind>element. This template immediately stamps the contents of its child templateinto the main document. Data bindings in an auto-binding template use the<dom-bind>element itself as the binding scope.
Polymer的数据绑定只能在template中,为了简化流程,使用自动绑定(<dom-bind>)能够在不定义新的自定义元素的前提下进行数据绑定。
注意:
dom-bind也提供了一个render方法来进行强制同步刷新。dom-bind同样也用一个mutableData属性来开关脏检测机制。When one of the template helper elements updates the DOM tree, it fires a
dom-changeevent.
当任意一个template helper elements更新了DOM树时,它们都会触发一个dom-change事件。
In most cases, you should interact with the created DOM by changing the model data, not by interacting directly with the created nodes. For those cases where you need to access the nodes directly, you can use the
dom-changeevent.
原则上,我们不应该直接与DOM进行交互,而应该修改对应的模型数据。如果的确需要这样做的话,可以监听这个的dom-change事件来完成。