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は将来的な方向性を提案する実装だと思うので、時系列の中で適当に棲み分けされるだろう。
ということで試してみたシリーズでした。