1. 程式人生 > WINDOWS開發 >Polymer API開發指南 (一)(翻譯)

Polymer API開發指南 (一)(翻譯)

翻譯的不好,輕拍

Polymer是google的一款前端開發框架,其基於Shadow DOM、Custom Elements、MDV等最新瀏覽器特性構建,代表了下一代Web框架的方向:一切皆元件、儘量減少程式碼量、儘量減少框架限制。

名詞解釋

  • Attribute: 元素宣告或者建立時需要的屬性。
  • Property: 屬性、元素或者類向外提供的資料區域,例如js物件的屬性。
  • Polyfill: 指的是通過第三方指令碼對老舊瀏覽器進行的修補,通過這些修補使之能夠支援新瀏覽器的特性。

Web components標準主要由以下3個部分組成:

  • Custom Elements
  • Shadow DOM
  • HTML Imports

元素宣告

Polymer的核心是Custom Elements,定義一個Polymer元素和定義一個普通的Custom Elements是差不多的。主要的區別就是Polymer使用polymer-element標籤進行宣告。

<polymer-element name="tag-name" constructor="TagName">
  <template>
    <!-- 在這裡放置shadow DOM -->
  </template>
  <script>Polymer(‘tag-name‘);</script>
</polymer-element>

Attrubtes

Polymer在polymer-element標籤上預留了一些特殊的attribute

Attribute 必要 描述
name Polymer元素名,名稱中需要包含"-"
attributes 指定元素的Published properties
extends 指定元素繼承其它元素
noscript 不需要呼叫Polymer()的簡單元素
constuctor 放置在全域性物件(如window)中的元素構造器名,允許使用者通過new來新建此元素.(如: var tagName = new TagName()

預設 Attribute

你在polymer-elemnet上設定的其他 attribute 將會自動新增到元素例項上。例如:

<polymer-element name="tag-name" class="active" mycustomattr>
  <template>...</template>
  <script>Polymer(‘tag-name‘);</script>
</polymer-element>

當一個tag-name例項被建立的時候,它就會自帶兩個預設 attributeclass="active"mycustomattr

<tag-name class="active" mycustomattr></tag-name>

Attribute大小寫

HTML解析器對 attribute 大小寫敏感是沒有必要的,但是Javascript卻對大小寫敏感。

書寫時你可以忽略屬性名的大小寫,但是當你執行並檢視元素的屬性列表時,屬性名永遠都是小寫的,Polymer會謹慎的將* property* 和 attribute 一一配對。例如:

<name-tag nameColor="blue" name="Blue Name"></name-tag>

在DOM中nameColor是小寫的,並且通常都會被忽略不處理。

下面例子也都會正常工作:

<name-tag NaMeCoLoR="blue" name="Blue Name"></name-tag>
<name-tag NAMECOLOR="red" name="Red Name"></name-tag>
<name-tag NAMEcolor="green" name="Green Name"></name-tag>

其它宣告元素的方法

考慮到重構的需要,我們有時候不會將指令碼放置在元素標籤裡,而是獨立成一個檔案。Polymer元素也可以通過外部指令碼中呼叫Polymer(‘tag-name‘)來建立。

<!-- 1. 在元素宣告內部新增外部指令碼 -->
<polymer-element name="tag-name">
  <template>...</template>
  <script src="path/to/tagname.js"></script>
</polymer-element>

<!-- 2. 在元素宣告之前新增外部指令碼 -->
<script src="path/to/tagname.js"></script>
<polymer-element name="tag-name">
  <template>...</template>
</polymer-element>

<!-- 3. 沒有指令碼 -->
<polymer-element name="tag-name" constructor="TagName" noscript>
  <template>
    <!-- shadow DOM here -->
  </template>
</polymer-element>

快速註冊

元素也可以只通過JS來註冊:



<script> Polymer(‘name-tag‘,{nameColor: ‘red‘}); var el = document.createElement(‘div‘); el.innerHTML = ‘ <polymer-element name="name-tag" attributes="name"> <template> Hello <span style="color:{{nameColor}}">{{name}}</span> </template> </polymer-element>‘; //如果不將這個元素宣告放入DOM內的話,custom elements的polyfill就找不到它。 document.body.appendChild(el); </script> <name-tag name="John"></name-tag>

需要注意的是,要將polymer-element放入DOM中,這樣custom element的polyfill才能找到它。

新增公開的property和方法

如果你想要定義一些方法或者 property 時(可選),在Polymer()的第二個引數中傳遞包含定義資訊的物件即可。

下面這個例子中,定義了一個property: message , 一個使用到了ES5 getter特性的property: greeting, 還有一個方法:foo

<polymer-element name="tag-name">
  <template></template>
  <script>
    Polymer(‘tag-name‘,{
      message: "Hello!",get greeting() {
        return this.message + ‘ there!‘;
      },foo: function() {...}
    });
  </script>
</polymer-element>

註釋: this是這個Polymer元素在自己內部他本身的引用。例如:this.localName == ‘tag-name‘.

注意: 當元素的property是一個js物件或者陣列時需要注意,由於prototype的一些特性,你可能會在同一類元素的不同實體中,陷入shared state問題。如果你想初始化一個property為物件或者陣列的時候,不要在prototype中賦值,而應該在created回撥中賦值。

// 正確
Polymer(‘x-foo‘,{
  created: function() {
    this.list = []; // Initialize and hint type to be array.
    this.person = {}; // Initialize and hint type to an object.
  }
});

// 錯誤
Polymer(‘x-foo‘,{
  list: [],// Don‘t initialize array or objects on the prototype.
  person: {}
});

新增私有或者靜態property

如果需要私有物件的話,將Polymer()放置在匿名自調函式裡即可。

<polymer-element name="tag-name">
  <template>...</template>


<script>
    (function() {
      // 只會執行一次
      var foo_ = new Foo();

      // 每一個例項建立時都會執行
      Polymer(‘tag-name‘,{
        get foo() { return foo_; }
      });
    })();
  </script>


</polymer-element>

支援全域性變數

有時候你希望定義一個全域性變數,並且在不同的元素中使用它。比如你會定義一個配置資訊,然後在其它部件中引用這個配置。或者一個運動曲線用於處理不同的動畫效果,或者一個變數用於儲存當前登入使用者的資訊。

你可以使用MonoState Pattern來實現這個目標。當定義一個Polymer元素時,定義一個閉包,將需要的變數放入進去,然後在元素的prototype上設定訪問器,或者在構造器裡把他們賦值到不同的例項上。

<polymer-element name="app-globals">


<script>
  (function() {
    var firstName = ‘John‘;
    var lastName = ‘Smith‘;

    Polymer(‘app-globals‘,{
       ready: function() {
         this.firstName = firstName;
         this.lastName = lastName;
       }
    });
  })();
  </script>


</polymer-element>

然後像使用其他元素一樣把它放置到另一個元素聲明裡,將需要的property繫結到例項上,這樣就可以使用Polymer的資料繫結技術來訪問它了。

<polymer-element name="my-component">
  <template>
    <app-globals id="globals"></app-globals>
    <div id="firstname"></div>
    <div id="lastname"></div>
  </template>
  <script>
    Polymer(‘my-component‘,{
      ready: function() { this.globals = this.$.globals; }
     });
  </script>
</polymer-element>

只要做一些輕微的調整,就可以在外部配置全域性變數的值了。

<polymer-element name="app-globals">


<script>
  (function() {
    var values = {};

    Polymer(‘app-globals‘,{
       ready: function() {
         for (var i = 0; i < this.attributes.length; ++i) {
           var attr = this.attributes[i];
           values[attr.nodeName] = attr.nodeValue;
         }
       }
    });
  })();
  </script>


</polymer-element>

在主頁中,專遞 attribute 就可以配置全域性變量了。

<app-globals firstName="Addy" lastName="Osmani"></app-globals>

元素生命週期方法

Polymer對於元素宣告週期回撥有著一流的支援,為了方便,回撥函式都用了簡短的名稱。

所有這些回撥都是可選的:

Polymer(‘tag-name‘,{
  created: function() { ... },ready: function() { ... },attached: function () { ... },domReady: function() { ... },detached: function() { ... },attributeChanged: function(attrName,oldVal,newVal) {
    //var newVal = this.getAttribute(attrName);
    console.log(attrName,‘old: ‘ + oldVal,‘new:‘,newVal);
  },});

下面是custom elements和Polymer元素的生命週期方法的對照表:

Custom Elements Polymer 觸發條件
createdCallback created 一個元素的例項被建立
- ready polymer-element已經完全準備好。(例如:shadow DOM建立完成,事件已繫結等等)
attachedCallback attached 當一個元素的例項被插入到DOM中
- domReady Called when the element’s initial set of children are guaranteed to exist. This is an appropriate time to poke at the element’s parent or light DOM children. Another use is when you have sibling custom elements (e.g. they’re .innerHTML‘d together,at the same time). Before element A can use B’s API/properties,element B needs to be upgraded. The domReady callback ensures both elements exist.
detachedCallback detached 當例項從DOM中移除
attributeChangedCallback attributeChanged attribute被新增移除或者改變。注意: 要監聽一個公開的property,應該使用 changed watchers

polymer-ready 事件

Polymer通過非同步的方式來處理自定義元素定義和升級。如果你在元素還沒有升級的時候,就通過DOM來獲取它,你只會得到一個HTMLUnknownElement。Polymer元素有時還會使用外部元素,例如css,如果他們還沒有完全載入完畢,就可能引起FOUC的問題。為了避免FOUC,Polymer只有在css等資源全部載入完畢之後才會註冊元素。

通過polymer-ready事件就可以得知元素何時註冊/升級完。

<head>
  <link rel="import" href="path/to/x-foo.html">
</head>
<body>
  <x-foo></x-foo>
  <script>
    window.addEventListener(‘polymer-ready‘,function(e) {
      var xFoo = document.querySelector(‘x-foo‘);
      xFoo.barProperty = ‘baz‘;
    });
  </script>
</body>

本文轉載於:猿2048→https://www.mk2048.com/blog/blog.php?id=h22kc2jh2bb