えいのうにっき

誤字脱字・記述の誤りなどはこちら https://github.com/a-know/blog.a-know.me へお願いします

AngularJSで動的に生成されるDOMに対して、jQueryプラグインの効果を適用する

**お久しぶりです お久しぶりです、a-knowです。 ブログを書くのは、昨年の12/11以来、半年弱ぶりですか・・・(汗) この半年、本当にいろいろありました。(思い出したくもないこともちらほらと・・・w)

お仕事の方も、今までやっていたPJとは違う、新しいPJが動き始めたということもあって、 バージョン管理をsvnからgitに変えたり(やっと!)、Jenkinsを導入したり、自社開発基盤を刷新したり・・・と、 技術的にも色んな新しいことに挑戦できている毎日なんですが、 AngularJSも、そのうちの一つだったりします。


**AngularJSでつまづいたところ それにしてもAngularJS、非常に痛快ですね! たとえば、jQueryで長々と書いていたDOM操作の為の記述が、ほぼいらなくなっちゃう。これはホントに痛快です。 最近は参加できていませんが、今後ハッカソンプログラミングコンテストなどの開発スピードが求められるような場に参加した際にも、デフォで使っちゃうだろうなー、というくらいに便利です。

そんな便利なAngularJSなんですが、やはりちょこちょこと躓いたりもしてます。 minify対策なんかもそうなんですが、 最近で一番手間取っちゃったのが、表題の「動的に生成されるDOMに対して、jQueryプラグインの効果を適用する」という点。

**jQueryスライダプラグイン「flickslide」を利用するのに手間取った 例をわざわざ用意するのも面倒なので、実際に躓いた事象を挙げます。 利用したのは、jQueryスライダプラグインflickslide」。モバイル向けにバナー画像を一定間隔でローテーションさせるUIを生成してくれるプラグインですね。 で、ローテーション対象である画像のDOMをAngularJSで生成している、と。 このflickslideに限らず、こういうかんじのプラグインは多いと思います。

では事例を。htmlはこんな感じで書きます。

|html|

||<

で、これにflickslideを適用するために、普通ならこう書けばいいんだけど、

|javascript| $(function(){ $('#mainImages ul li').flickSlide({target:'#mainImages>ul', duration:5000}); }); ||<

これだと、AngularJSで動的に生成されたDOMに対して正しく適用させることができない。 どうするか。

directiveを設定するのが正解っぽい。 directiveってなんぞや、ってところですけど、「ng-hoge」みたいなものを自分で定義・設定できるようになる、みたいな感じの理解です。

まず、ng-appを設定して、

|html| ||<

directiveを設定。

|javascript| angular.module('testApp', ) .directive('flSlide', function factory() { return function postLink(scope, iElement, iAttrs) { //ごにょごにょする } }; }) ||< |html|

||<

JSの方で「flSlide」と設定すれば、htmlの方では「fl-slide」と、こういう書き方になります。 んで、「iElement」は、そのdirectiveが設定された要素を指すイメージ。 なのでこの例だと、「images」のサイズが5だと、directiveも5回、呼び出されるかんじ。

この「ごにょごにょ」のところに、実施したいことを記述するわけで、 今回の場合は

|javascript| $(function(){ $('#mainImages ul li').flickSlide({target:'#mainImages>ul', duration:5000}); }); ||<

これに相当することを書きたいわけで、 「iElementは '#mainImages ul li' と同じだから〜・・・」とかいろいろ考えちゃうんですが、 flickslideの場合でいうと、結論、下記のように書くのが正解っぽい。

|javascript| angular.module('testApp', ) .directive('flSlide', function factory() { return function postLink(scope, iElement, iAttrs) { //最後の一回だけ適用 if(scope.$last === true){ $('#mainImages ul li') .flickSlide({target : '#mainImages>ul', duration : 5000}); } } }; }); ||<

自分的には、ずっとiElementを使おうとして(使わなきゃいけないと思って)躓き続けちゃっていました。 元々の記述で行われる処理をdirectiveで実施するだけ、というふうに、はやく頭を切り替えられれば良かった。。

ちなみにこのflickslideプラグイン、コードにプログラムミスがあると思うんだよなぁ。。

いくらdurationに値を設定しても、実際のアニメーションには反映されない。

自分で直しちゃったけど。。

**おまけ・AngularJSを使って開発をスタートするためにやったこと ドットインストール。全部見ても30分。全くの予備知識もないところに見るのには最適。 公式サイトAPIリファレンスがすごく探しやすい。最終的な検索結果とはあまり関係のないワードを入力しても、結構目的のページに行き着けちゃう印象。

・・・僕はこれだけ。w あとはひたすら作る!手を動かす!・・・これですね☆

仕事仲間もつぶやいてたんだけど、例えばng-controllerの好ましい設定範囲は?とか、

AngularJSに関してはまだまだ疑問は尽きないかんじ。

ぜひ勉強会とかに参加して基礎を固めたいな、というところ。

**関連エントリ blog.a-know.me

Webアプリ構築のためのAngularJS

Webアプリ構築のためのAngularJS

follow us in feedly