Polymer で x-ahomu 要素をつくった
Posted: Updated:
デモをiframeに食わせてるだけなので、モバイルだとよく分からない状態だと思われる。ソーリー。要素のインスペクトすると、ちゃんと <x-ahomu>
があるのを確認できるはず。
<x-ahomu>
去年Googleのイベントで話を伺ってから、Web Components/Polymer に対しては好意的なつもりなので、改めて試してみた。要素としての設計はやっつけだけど、実装の手触りだけ。
アッサリとした構成の x-imager を参考に作ったのだけれど、ボイラープレートはpolymer-boilerplateなので、そっちで作った方がしっかりしてるようには見えそう。
以下、実装時の適当なメモなど。
例えば polymer-ajax
<polymer-ajax url="https://api.github.com/users/ahomu/repos" auto handleAs="json" response="{{repos}}"></polymer-ajax>
polymer-ajax.htmlのdocコメントを見ると、使い方がなんとなくわかる。attributes=
で示されているプロパティは、polymer-ajax
要素を書くときの属性値で上書きできる。
ここでは、自分のGitHubリポジトリのAPIを叩いて、それを handleAs
でJSONとして扱い、レスポンスを {{repos}}
にバインディングしている。
polymer-ajax
が XMLHttpRequestまわりの機能要素を分化して polymer-xhr
を内包しているのも興味深い。
ライフサイクルコールバック
<script>
Polymer('x-ahomu', {
created : function() { /* インスタンスが生成された直後のとき */ },
ready : function() { /* ShadowDOMとか要素の準備ができたとき */ },
attached: function() { /* 要素がドキュメントに追加されたとき */ },
detached: function() { /* 要素がドキュメントから削除されたとき */ }
});
</script>
要素のライフサイクルにおける各タイミングでは、要素に定義したコールバックが呼び出される。 ready
でアレコレしとけば困ること少なそう。
イベント
<template>
<button on-click="{{changeColor}}" change-to-color="mono">Mono</button>
<button on-click="{{changeColor}}" change-to-color="rainbow">Rainbow</button>
<button on-click="{{changeColor}}" change-to-color="green">Green</button>
</template>
<script>
Polymer('x-ahomu', {
// 前略
changeColor: function(e) {
this.color = e.currentTarget.getAttribute('change-to-color');
},
// 以下略
});
</script>
DOMイベントはこんな感じで、要素に定義したハンドラをバインディングできる。よくあるMVVM風味。
ここではイベントの発生によって this.color
を変更しているが、属性値の変更は attributeChanged
のコールバックで捉えられる。
ユーザーアクションを要素の外側にイベントを通して作用させるには、this.fire(eventName, dataObj)
で発火させることで、外側から addEventListener
で捉えられる。
Filter とか <template> とか
<template>
<ul>
<template repeat="{{ repo in repos | rejectForkedRepos }}">
<li><a href="{{repo.html_url}}">{{repo.name}}</a></li>
</template>
</ul>
</template>
<script>
Polymer('x-ahomu', {
// 前略
rejectForkedRepos: function(repos) {
repos = repos || [];
return repos.filter(function(r) { return r.fork === false });
},
// 以下略
});
</script>
さすがにAngularJSと酷似する趣になるが、Filterを実装することができる。データバインディングに対するFilterって、機能的に必要なのは分かるけど、うーんPolymerとしての便利機能だからいいのかな。
実装メモはここまで。
Polymerのサイトが新しくなっていた
Polymer hits "Alpha": new logo, new look, new beginner content. Check out http://t.co/Csl5oTyXER
— Polymer (@polymer) February 20, 2014
大体このあたりのドキュメントを読めば、振る舞いを実装すること自体はすぐにできるはず。ただし、実際にPolymerで実装すべき要素に思いを馳せて作ろう思うと、グローバルに再利用可能な振る舞い・カプセル化を実装するためにいくつか意識すべき点がありそう。
- Functional. The browser already knows what to do with a <select> element. When it encounters <select> in markup it creates an interactive control for the user.
- Reusable. The <select> element is a reusable package of functionality that you don’t have to implement yourself.
- Interoperable. Every JavaScript library knows how to interact with DOM elements.
- Encapsulated. It keeps its internals all tucked away, so including one won’t break the rest of your page.
- Configurable. You can configure its behavior with HTML attributes, without using any script.
- Programmable. If you grab the element from the DOM it also has methods and properties for things that don’t make sense in markup.
- Event Generator. It dispatches events to let you know when something interesting happens.
- Composable. Not only can you include a <select> inside of most other kinds of element, its behavior can also change depending on which things you put inside of it. Understanding Polymer - Polymer
上記の引用における、ファンクショナル・再利用性・相互運用性・カプセル化・設定可能性・プログラマブル・イベント生成・コンポーザブル、という要素を要素たらしめる特徴の話。
このあたりまでくるとComponentのことも気になってくるが、Componentは直近の現実解になる思想の実装であり、WebComponents/Polymerは将来的な方向性を提案する実装だと思うので、時系列の中で適当に棲み分けされるだろう。
ということで試してみたシリーズでした。