#daiizメモ

Scrapboxに夢中

Polymer 1.0 でカスタムHTMLタグをつくる

昨日の記事に引き続き、Polymerの話です。今日は以下のPolymer公式ページ

Publish an element - Polymer Project

を読みながら、reusableなelementをつくります。ブログを書きながらプログラムを書いていきます。ブログ駆動開発!!!

初回のみ

npmでpolyserveというものをインストールする。polymerではimportタグを使っており、これはサーバーから色々読み込むので開発中はローカルサーバーを立てる必要がある。index.htmlをダブルクリックして開いてもimportされないので注意。ということで、-gを付けてnpm:

$ npm install -g polyserve

一回やればもう次回以降はやらなくてOK

seed elementを貰う

冒頭で紹介した公式ページで種が配られているのでもらってきて、フォルダの名前をこれからつくるelementの名前にする。最低限必要なものが用意されているのですぐに書き始められる。便利。
seed element: https://github.com/PolymerElements/seed-element/archive/v1.0.0.zip

今回はサンプルとして、価格と税率を与えると、税込価格を表示してくれるWeb Componentsを作ってみようと思うので、price-taxという名前にする。フォルダ内のseed-element.htmlprice-tax.htmlに改名する。

いまのところのフォルダ内の様子はこんな感じ:

続いて

$ bower install

を実行すると、bower_components/ にPolymerが配置される。

どこに何を書くか & 実行方法

まずは簡単に捉える。

  • /price-tax.html: カスタムエレメントの本体を記述する
  • /demo/index.html: カスタムエレメントを使用している様子を書く

demoを実行するには、

$ polyserve

して、ブラウザで

http://localhost:8080/components/seed-element/demo/

を開けばよい。

使用シーンからつくる

どのように使いたいかを考えると、想像が膨らむと思うので、まずは/demo/index.htmlから書いてみる。

<price-tax price=2000 rate=8 switchable>カルビ盛合せ</price-tax>
<price-tax price=500  rate=8 switchable>生ビール</price-tax>
<price-tax price=600  rate=8 switchable>牛タン</price-tax>
  • price: 単価(円)
  • rate: 消費税率(%)
  • switchable: 税込/税別の表示を切り替えるUIを提供する

という感じに使う例を書いた:

本体を書く

これから、/price-tax.htmlに書いていく。

まずは、最初に付いてきたscriptタグは気にしないで、見た目から作ってみる。気にしないと言っても、

<script>
    Polymer({
        is: 'price-tax',
        properties: {
            price: Number,
            rate: Number,
            switchable: Boolean
        }
    });
</script>

くらいは、書いておく必要がある。 <dom-module>のidをprice-taxに変更して、中身の<template>を書く。以下のように書けば、とりあえず、メニュー名を表示できる。

<template>
    <span id="menu">
        <content></content>
    </span>
</template>

うまく動いたので、price属性に与えられた値も表示するようにしてみる。

<template>
    <span id="menu">
        <content></content>
    </span>
    <span id="total">{{price}}</span>
</template>

次は、priceとrateの値を用いて税込価格を計算する。priceやrateを参照するには、this.priceなどと書けば良い。最初に書いたJSにreadyを追加して、以下のようにする。

Polymer({
    is: 'price-tax',
    properties: {
        ...
    },

    ready: function () {
        var tax = Math.floor( this.price * this.rate / 100 );

        console.info( this.price + tax );
    }
});

これで、コンソールに2160が表示される。この値をブラウザ上に表示したいので、this.$$(selector)を用いて span#total を取得し、これに値をセットする。ready内を以下のように書き換えるだけで良い。

ready: function () {
    var tax = Math.floor( this.price * this.rate / 100 );

    this.$$('#total').innerHTML = this.price + tax;
}

最後に、switchableが提供する「税込/税別の表示を切り替えるUI」として、selectboxを配置してみる。selectboxにはchangeイベントを仕掛けておいて、チェックのON/OFFが変わる度に値段を更新できるようにする。

<template>の最後に

<input type="checkbox" checked on-change="handleChanged" id="way">税込み

を追加して、JSにイベントハンドラ

handleChanged: function (e) {
    console.log(e.target.checked);
}

を追加すれば、checkboxの変化を監視することができる。ここで変化をキャッチしたら、readyでやったこととおなじようなことをもう一度やれば良い。readyでの処理を一つの新たな関数computePriceにまとめて、this.computePrice( )を呼ぶようにする。つまり、

ready: function () {
    this.computePrice();
},

handleChanged: function (e) {
    this.computePrice();
},

computePrice: function () {
    var tax = 0;
    if (this.$$('#way').checked) {
        tax = Math.floor(this.price * this.rate / 100);
    }
    this.$$('#total').innerHTML = this.price + tax;
}

ついでに、属性pricerateが外部から変更されたときも自動で更新されるように、イベントを仕掛けておくことにする。 やることは簡単で、最初の方に書いたpropertiesを

properties: {
    price: {
        type: Number,
        observer: '_priceChanged'
    },
    rate: {
        type: Number,
        observer: '_rateChanged'
    },
    switchable: Boolean
  },

のように書き換えて、それぞれのobserverを定義すれば良い。_priceChangedや_rateChangedは、関数computePriceを実行するだけで良い。


できあがった /price-tax.html はこちら:

動作例

デモを動かすと、こんな感じでメニュー表みたいなものが見られる。

今回はここまで。お疲れ様でした!!!

参考

今日作ったもの