1

之前一篇算是带大家大致领略了一下Polymer的风采。这篇我们稍微深入一丢丢,讲下组件的注册和创建。

创建自定义组件的几种方式

这里我们使用Polymer函数注册了一个自定义组件"my-element"

// register an element
Polymer({
  is: 'my-element',
  created: function() {
    this.textContent = 'My element!';
  }
});

在hello world篇中我们使用的是直接在html页面里写标签的方式来创建这个自定义组件

<div>
    <my-element></my-element>
</div>

但是如果my-element需要被动态创建,使用上面的方式显然就满足不了要求。所以Polymer提供了另外2种创建方式
第一种

var element = document.createElement('my-element');

啊,我们可以调用原生dom api一样来创建自定义组件了,这是一件多么让人愉悦的事情。
我们来测试一下
图片描述

第二种
这种方式需要我们在注册自定义组件的时候进行一点小的改动,调用Polymer函数定义的时候把返回值赋个一个全局变量MyElement

// register an element
MyElement = Polymer({
  is: 'my-element',
  created: function() {
    this.textContent = 'My element!';
  }
});
var el2 = new MyElement();

从这里可以得知Polymer函数会返回一个自定义组件的构造函数,使用new就可以创建它了。
我们来测试一下
图片描述

对于这种方法,Polymer还提供了一个接口factoryImpl可以让我们在创建自定义组件的时候传入运行时的构造参数,而不是只能死死地使用注册组件时候定义的内容。
我们修改下例子

<dom-module id="my-element">
    <template>
        <p>{{helloMessage}}</p>
    </template>
    <script>
        MyElement = Polymer({
            is: 'my-element',
            properties: {
                helloMessage: {
                    value: "hi",
                    type: "string"
                }
            },
            //定义factoryImpl借口,构造时将helloMessage重新赋值
            factoryImpl: function (message) {
                this.helloMessage = message;
            }
        });
    </script>
</dom-module>

测试一下
图片描述
这种构造函数传参的方式只适用于,new CustomElement的创建方式,而且它2种方式不支持,原因你自己拍脑袋想想就懂了。

factoryImpl 被调用的时机是在dom被创建,默认值被设置了以后,具体的我们会在生命周期篇里谈。

扩展原生的html标签

首先告诉大家一个非常遗憾的消息,Polymer当前版本暂不支持扩展自己定义组件(既自己不能扩展自己,但是会在以后版本中支持大家请擦干净鼻涕静静等待),目前只能扩展原生的html标签如input, button等。Polymer提供了一个extends接口来实现扩展

my-input.html

<script>
    MyInput = Polymer({
        is: 'my-input',
        extends: 'input',
        created: function () {
            // 我们扩展组件的外观使之变成红色边框
            this.style.border = '1px solid red';
        }

    });
</script>

图片描述

如果使用的是dom api我们需要这样来创建

var el1 = document.createElement('input', 'my-input')

如果使用html标签的方式,我们要这样写

<input is="my-input">

窃以为,后面2种方式来创建一个组件是非常非常扯蛋的一件事情,使用者必须非常清楚组件的继承关系,你说这还不扯蛋么?期望Polymer在后续版本的api中对于组件扩展这一块内容,消灭以上两种不靠谱的创建方式。

在html主文件里定义“自定义组件

首先说下,只有在写demo的时候,才会用到这种写法。生产环境中,都是需要把组件写在各自独立的文件中。

<!DOCTYPE html>
<html>
  <head>
    <script src="bower_components/webcomponentsjs/webcomponents-lite.js">
    </script>
    <link rel="import" href="bower_components/polymer/polymer.html">
    <title>Defining a Polymer Element from the Main Document</title>
  </head>
  <body>
    <dom-module id="main-document-element">
      <template>
        <p>
          Hi! I'm a Polymer element that was defined in the
          main document!
        </p>
      </template>
      <script>
        HTMLImports.whenReady(function () {
          Polymer({
            is: 'main-document-element'
          });
        });
      </script>
    </dom-module>
    <main-document-element></main-document-element>
  </body>
</html>

HTMLImports.whenReady()这个方法你可以把它理解成JQ里的document.ready()或者AMD里的domReady(),可以确保引用的组件dom都被加载完了再进行下一步的调用,一般都是用在index.html也就是程序的入口处。


熊丸子
5.6k 声望293 粉丝

现在sf的文章质量堪忧~~~