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.is, 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




element.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.


classclassList, classNameMaps to two properties with different formats.
stylestyleBy specification, style is considered a read-only reference to a CSSStyleDeclaration object.
data-*datasetCustom data attributes (attribute names starting with data-) are stored on the dataset property.
valuevalueOnly 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.is, 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$="https://www.example.com/profiles/[[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('myArray.1.name', 'Rupert');

    customElements.define(XCustom.is, 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}}">
local_offer #Polymer