2

公开 property

当你公开一个 Polymer 元素的 property 名字时,就等于把这个 property 设置为公开API了。公开 property 会有如下的特性:

  • 支持声明数据双向绑定
  • 通过声明,property 将会按照名称一样的 html attribute 初始化数据
  • property 的值可以反射到元素对应的attribute上

注: property 名称是大小写区分的,但是 attribute 却不是。polymer 将会把 property 和 attribute 一一对应,所以你不能声明两个只有大小写区别的 attribute(比如:name 和 NAME);

有两种方法可以绑定 property :

  • 将property名放在polymer-element元素attributes attribute里
  • 将property名放在构造原型的publish

举个例子,这里一个元素,通过设置attributes来设置三个公开的property,foo,bar,baz

<polymer-element name="x-foo" attributes="foo bar baz">
  <script>
    Polymer('x-foo');
  </script>
</polymer-element>

下面这个例子用到了publish

<polymer-element name="x-foo">
  <script>
    Polymer('x-foo', {
      publish: {
        foo: 'I am foo!',
        bar: 5,
        baz: {
          value: false,
          reflect: true
        }
      }
    });
  </script>
</polymer-element>

主要注意的是baz使用了不同的声明方法来开启 attribute 反射功能。

一般来说,我们更建议使用attributes,因为这是声明式的,而且开发者可以很容易的通过元素标签来看到所有元素暴露出来的API。

只有以下情况,我们才建议使用publish式声明:

  • 元素公开的property太多,把所有property名放在attributes会显得有点奇怪。
  • 需要设置property的初始值。
  • 你需要设置attribute到property之间的反射

property 的默认值

默认情况下,在attributes里设置的property的值为null

<polymer-element name="x-foo" attributes="foo">
  <script>
    // x-foo 有一个名称为 foo 的 property ,默认值为 null
    Polymer('x-foo');
  </script>
</polymer-element>

polymer会将foo添加到元素prototype上,并设置为null
你可以通过在元素的prototype上显式property的默认值。

<polymer-element name="x-foo" attributes="bar">
  <script>
    Polymer('x-foo', {
      // x-foo 有一个名称为 bar 的 property ,默认值为 false
      bar: false
    });
  </script>
</polymer-element>

或者可以全部移到publish里:

<polymer-element name="x-foo">
  <script>
    Polymer('x-foo', {
      publish: {
        bar: false
      }
    });
  </script>
</polymer-element>

如果property的默认值为object或者array的时候,则需要放在created里初始化,这样就保证了在不同的实例里值的引用都不同。

<polymer-element name="x-default" attributes="settings">
  <script>
    Polymer('x-default', {
      created: function() {
        // create a default settings object for this instance
        this.settings = {
          textColor: 'blue';
        };
      }
    });
  </script>
</polymer-element>

通过设置 attribute 来配置元素

Attribute 为我们提供了一种简单的方法来直接配置元素。我们可以通过设置attribute为元素提供一个初始值,从而来自定义它。

<x-foo name="Bob"></x-foo>

如果元素的property不是字符串,那么polymer会自动判断它的类型,并将其转换为合适的格式。
除非开启了attribute反射,否则Attribute到property的连接是单向的,property改变并不会影响到attribute。

注:不要将数据绑定和attribute配置混淆。数据绑定是引用式的,这就意味着值并不会被序列化和反序列化。

探测property类型

Polymer会根据property的默认值,来判断它的类型,并将相绑定的attribute转换为此类型。

例如一个元素x-hint有一个property名为count,默认值为0

<x-hint count="7"></x-hint>

因为count的默认值为0,所以polymer将字符串"7"转换成了数字7

如果一个property是对象或者数组,则我们可以用JSON字符串来表示它。

<x-name fullname='{ "first": "Bob", "last": "Dobbs" }'></x-name>

这就相当于在JS里设置元素的propertyfullname

xname.fullname = { first: 'Bob', last: 'Dobbs' };

我们可以在publish或者created回调中设置默认值。下面这个元素使用了三种方法。

<polymer-element name="hint-element" attributes="isReady items">


<script>
    Polymer('hint-element', {

      // hint that isReady is a Boolean
      isReady: false,

      publish: {
        // hint that count is a Number
        count: 0
      },

      created: function() {
        // hint that items is an array
        this.items = [];
      }
    });
  </script>


</polymer-element>

重要:对于类型为对象或者数组的property,应该始终在created回调中初始化。如果直接在构造原型上设置默认值的话,那么在不同的实例里就会遇到 "shared state" 错误。

Property 反射到 Attribute

Property的值可以反射到对应的Attribute上。例如,如果在一个元素上开启了对name的反射,那么this.name="Joe"的效果就等于 this.setAttribute('name','Joe'),元素将会自动的更新DOM。

<x-foo name="Joe"></x-foo>

Property 反射只在某些特殊的场景有用,所以它默认是关闭的,它最常用的地方就是用attribute来控制元素的样式。

待续...


时允
4.9k 声望112 粉丝

美团成都部门招聘 RD,有意者联系我