ぶるーすくりーん

ぽんこつプログラマ日記

Polymer Custom Elementを作成してみる

前回Polymerを使ってみて、Web componentってステキな仕様だなと思ったので、使ってみるだけでなくCustom Elementの作り方について学んでみました。

いろいろ読んでるうちに、Polymerってこれから来る(かもしれない)Web component時代のためのすてきメソッドだとやっと理解できました。

Polymerとは

ブラウザがWeb componentに対応/非対応に関わらず利用できるようにした、Google社が提供するjsのライブラリ。 この 考え方 をPolyfill(ポリフィル)と呼ぶ。

Web componentの概念はWEB+DB Vol.81読むとちょっとわかるかも。

Custom Elementをつくってみる(しんぷる編)

こんな感じのディレクトリ構成でつくってみます。

root
├── bower.json
├── bower_components
├── elements
│   └── menu-panel
├── gulpfile.js
├── index.html
├── node_modules
└── package.json

Polymer install

$ bower init
$ bower install --save Polymer/polymer
$ bower install --save Polymer/platform

template HTMLの作成

ここでは、menu-panel.htmlという名前で作成していきます。

<link rel="import" href="../../bower_components/polymer/polymer.html">

<polymer-element name="menu-panel" noscript>
  <template>
      <nav class='menu-panel'>
        <a href='#'>Home</a>
        <a href='#'>List</a>
        <a href='#'>Message</a>
        <a href='#'>Profile</a>
      </nav>
  </template>
</polymer-element>

polymer-elementタグの要素

  • name: 必須要素。-を必ず含まなければならない。HTMLタグとして使用する名前を指定する。 (ここではmenu-panel).
  • noscript: スクリプトを含まないシンプルなElementであることを示す場合に指定。noscriptの指定があるElementは自動的に登録される。

ロード用のHTML作成

Elementを使用するindex.htmlを作成。

<!DOCTYPE html>
<html>
  <head>
    <script src="bower_components/platform/platform.js"></script>

    <link rel="import" href="elements/menu-panel/menu-panel.html">
  </head>
  <body>
    <menu-panel></menu-panel>
  </body>
</html>

確認用に環境整備

修正しながら確認できるようにgulpとBrowserSyncを設定

$ bower install gulp browser-sync --save-dev

gulpfile.jsに以下を記述。

var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;

gulp.task('serve', function () {
  browserSync({
    notify: false,
    server: {
      baseDir: ['./']
    }
  });

  gulp.watch(['./*.html', './elements/**/*.html'], reload);
  gulp.watch(['./*.css', './elements/**/*.css'], reload);
  gulp.watch(['./*.js', './elements/**/*.js'], reload);
});

サーバ起動。

$ gulp serve

こんな画面が表示されればOK。

SimpleElement.png

Custom Elementをつくってみる(script編)

変数を渡してみる(データバインディング

menu-panel.htmlを編集して簡単な変数渡しをしてみます。

<link rel="import" href="../../bower_components/polymer/polymer.html">

<polymer-element name="menu-panel">
  <template>
      <nav class='menu-panel'>
        <a href='#'>{{item}}</a>
        <a href='#'>List</a>
        <a href='#'>Message</a>
        <a href='#'>Profile</a>
      </nav>
  </template>
  <script>
    Polymer('menu-panel', {
      item: "hoge"
    });
  </script>
</polymer-element>

先ほどの例で記述したnoscript要素をはずし、scriptタグ内の定義を追加しています。
また、メニュー項目の先頭を{{item}}として、値を設定できるようにします。

以下のように先頭がjs内で指定した「hoge」に変わるのが確認できればOKです。

DataBinding.png

リスト形式で渡してみる(データバインディング応用編)

次は、リスト形式で変数を渡してみます。

<link rel="import" href="../../bower_components/polymer/polymer.html">

<polymer-element name="menu-panel">
  <template>
    <nav>
      <template repeat='{{item in items}}'>
        <a href="#{{item.tag}}">{{item.name}}</a>
      </template>
    </nav>
  </template>
  <script>
    Polymer('menu-panel', {
      ready: function() {
        this.items = [
          {tag: '', name: 'Home'},
          {tag: 'list', name: 'List'},
          {tag: 'message', name: 'Message'}
        ];
      }
    });
  </script>
</polymer-element>

これは、PolymerのtemplateのData Binding機能を使用しています。 詳しくはこのへん参照。

ポイントは、repeat要素でitemsで渡されたリストをクルクルしてるところです。
あと、templateタグには以下のような決まりがあるそうなので、一個トップレベルのtemplateをかましているところです。(下の説明を読む分には、余計にかまさなくてもいい気もするのですが、template内で使用するタグによって展開されたりしなかったりしました。)

In a Polymer element declaration, the first (top-level) template element is used to define the custom element’s shadow DOM.

Inside a Polymer element, you can use templates with data binding to render dynamic content.

  • the first (top-level) template element はカスタムElementの shadow DOM の定義に使用される。
  • Polymer elementの内側では, template をデータバインディング用に使用できる。

まとめ

というわけで、なんとなくCustom Element作成できそうなので、次はPolymer使って、簡単なWebサイト作成してみたいと思ってます。