Angular.jsは優れたフレームワークだ。ただ、使ってみると問題と感じる点もある。
具体的には、Viewが片手落ちな点だ。
通常はHTML DOMがView・モデルとなるJavaScriptオブジェクトをcontrollerでバインディング、これで問題ない。しかし、jQuery Plugin(jQuery UI draggable等)で加工したい場合その処理を普通に書ける場所がない。
これらの処理はDOMレンダリング後に行う必要があるが、 Angular.jsではafter renderのイベントがAPIにない(ng-rendered的なものがない) のだ。
では、追加されるdivに$("#id").draggable()
などをしたい時、どこで実行できるのか?
結論としては、directive
を使用する。 directive
を使用するんだ(二回)。
実例としてjsFiddleのサンプルを用意したので、こちらを参照されたし。これは、明確にMVCを分割することを意識して書いている。
これを書き終えてからカーリングというスポーツを根本的に勘違いしていたことに気づいたが、そんなことは問題ではない。Angular.jsにはdirectiveという仕組みが用意されており、これを利用することでレンダリング処理に介入できる。つまり「V」における片手落ち部分を補完できるのだ。
実際はもっと色々な使い方ができるので、公式ドキュメントなどをぜひ参照されたし(分かりにくいけど・・・ここはノウハウが溜まったらまとめたい)。
なお、controller内ではまだレンダリングが開始されていないため、jQuery Plugin等の処理は記述できない。強制的に$scope.$apply()
でレンダリングを走らせられるが、デフォルトの処理とかぶっておかしくなるので注意が必要だ。
これが役に立つのが、モバイルデバイス対応だ。Angular.jsにはタッチ系イベントのための属性がないため、モバイル対応をする際はHammer.jsなどで自分で対応することになる。この実装をする際、directiveを使えばDOMのイベントハンドラを拡張することができる。
directiveに書かず外部でイベントを検知して$scope
のメソッドを実行する方法もあるが、この際はangular.element($("xxx")).scope();
で$scope
オブジェクトを取得できるということを覚えておけば対応できるだろう。
最後に・・・これは愚痴だ。これを読んでも読まなくても差し支えない。
2013/11現在、Angular.jsはStableが1.0.8で開発中が1.2.0。マイナーバージョンにして2の開き。有権者の方に訴えたいのは、こんなに開いていてOKなのでありましょうか、ということだ。
→とブツブツ言っていたが、Angular.jsは1.1が開発中で1.2が次期安定版として使い分けられているので、この状態は全く普通なのだった(こちら参照)。
ただ、現在のStable(1.0.x)にはまだngIf
などのあったらすぐに使いたい便利属性がないのは事実。
Angular.jsのAPIドキュメントを見る際は、バージョンを選択することを忘れないようにして新バージョンのリリースを待とう!