Skip to content

Polymer 2.0 文档笔记(6) Data Binding

A data binding connects data from a custom element (the host element) to a property or attribute of an element in its local DOM (the child or target element). The host element data can be a property or sub-property represented by a data path, or data generated based on one or more paths.


Anatomy of a data binding


<custom-element property-name=annotation-or-compound-binding ></custom-element>
<custom-element attribute-name$=annotation-or-compound-binding></custom-element>
  1. =绑定property,$=绑定attribute(href,style,...)
  2. annotation代表数据绑定标记: [[ ]]或者\{\{ \}\}
  3. compound-binding:包含标记的字符串: "my name is {{ name }}"

Bind to a target property

将target元素的name属性绑定到当前元素的my-Name属性。 注意驼峰式和dash式命名的转换规则(property name to attribute name mapping)

<target-element name="{{myName}}"></target-element>

Bind to text content


<dom-module id="user-view">

    class UserView extends Polymer.Element {
      static get is() {return 'user-view'}
      static get properties() {
        return {
          name: String

    customElements.define(, UserView);

<!-- usage -->
<user-view name="Samuel"></user-view>

Binding to text content is always one-way, host-to-target.

注意,文字节点的绑定永远都是单向的(host to target)

Bind to a target attribute


property绑定相当于 = 'value'


  <!-- Attribute binding -->
  <my-element selected$="[[value]]"></my-element>
  <!-- results in <my-element>.setAttribute('selected', this.value); -->

  <!-- Property binding -->
  <my-element selected="{{value}}"></my-element>
  <!-- results in <my-element>.selected = this.value; -->
需要注意的是: attribute形式的数据绑定只能是单向的([[ ]])

Native properties that don't support property binding

There are a handful of common native element properties that Polymer can't data-bind to directly, because the binding causes issues on one or more browsers.


Attribute Property Notes
class classList, className Maps to two properties with different formats.
style style By specification, style is considered a read-only reference to a CSSStyleDeclaration object.
href href
for htmlFor
data-* dataset Custom data attributes (attribute names starting with data-) are stored on the dataset property.
value value Only for <input type="number">.

data binding to the value property doesn't work on IE for numeric input types. For this specific case, you can use one-way attribute binding to set the value of a numeric input. Or use another element such as iron-input or paper-input that handles two-way binding correctly.

<!-- class -->
<div class$="[[foo]]"></div>

<!-- style -->
<div style$="[[background]]"></div>

<!-- href -->
<a href$="[[url]]">

<!-- label for -->
<label for$="[[bar]]"></label>

<!-- dataset -->
<div data-bar$="[[baz]]"></div>

<!-- ARIA -->
<button aria-label$="[[buttonLabel]]"></button>

Logical not operator


  <my-page show-login="[[!isLoggedIn]]"></my-page>

  1. 逻辑非只能用在单项绑定中使用
  2. 只能有一个!不能!!

Computed bindings

computed binding类似于computed property。

<div>[[_formatName(first, last, title)]]</div>

An element can have multiple computed bindings in its template that refer to the same computing function. 一个元素里面可以有多个使用同样的computing function的computed binding

computed binding并不完全等同于computed property,差异有下面几点:

  • computed binding的依赖路径是相对于元素当前的data scope的
  • computed binding的参数不仅可以有computed property那样的路径参数,也可以是单纯的字符串或者数字等
  • computed binding可以没有参数,这种情况下,函数只会被调用一次
  • computed binding函数要等所有的参数中的依赖全部初始化(!=undefined)之后才会执行
<dom-module id="x-custom">

    My name is <span>[[_formatName(first, last)]]</span>

    class XCustom extends Polymer.Element {
      static get is() {return 'x-custom'}
      static get properties() {
        return {
          first: String,
          last: String
      _formatName(first, last) {
        return `${last}, ${first}`


    customElements.define(, XCustom);


Commas in literal strings: Any comma occurring in a string literal must be escaped using a backslash (\).


<dom-module id="x-custom">
    <span>{{translate('Hello\, nice to meet you', first, last)}}</span>

Computed bindings are one-way. A computed binding is always one-way, host-to-target.

computed binding只能在单向绑定中使用

Compound bindings


<img src$="[[userId]].jpg">

<span>Name: [[lastname]], [[firstname]]</span>

  1. undefined会输出成空字符串
  2. Compound binding永远是单向绑定,虽然你也可以使用\{\{ \}\}记号。

Binding to array items

To keep annotation parsing simple, Polymer doesn't provide a way to bind directly to an array item.


<!-- Don't do this! -->
<!-- Or this! -->

有下面几种方法可以解决: - dom-repeat里面已经为每个数组里面的元素创建了一个子scope,因此可以直接binding - array-selector 同上,可以直接绑定一个元素或者被选择的元素集合 - 使用computed binding来间接绑定,见下面例子

<dom-module id="x-custom">

    <div>[[arrayItem(myArray.*, 0, 'name')]]</div>
    <div>[[arrayItem(myArray.*, 1, 'name')]]</div>


    class XCustom extends Polymer.Element {

      static get is() {return 'x-custom'}

      static get properties() {
        return {
          myArray: {
            type: Array,
            value: [{ name: 'Bob' }, { name: 'Doug' }]

      // first argument is the change record for the array change,
      // change.base is the array specified in the binding
      arrayItem(change, index, path) {
        // this.get(path, root) returns a value for a path
        // relative to a root object.
        return this.get(path, change.base[index]);

      ready() {
        // mutate the array
        this.unshift('myArray', { name: 'Susan' });
        // change a subproperty
        this.set('', 'Rupert');

    customElements.define(, XCustom);


Two-way binding to a non-Polymer element


<!-- Listens for `input` event and sets hostValue to <input>.value -->
<input value="{{hostValue::input}}">

<!-- Listens for `change` event and sets hostChecked to <input>.checked -->
<input type="checkbox" checked="{{hostChecked::change}}">

<!-- Listens for `timeupdate ` event and sets hostTime to <video>.currentTime -->
<video url="..." current-time="{{hostTime::timeupdate}}">

<!-- Listens for `value-changed` event -->
<my-element value="{{hostValue::value-changed}}">

<!-- Listens for `value-changed` event using Polymer convention by default -->
<my-element value="{{hostValue}}">