ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

ここ最近AngularJSで困った・ハマったことを記す

AngularJS Hackathon

新規プロジェクトになりそうな案件に携わりプロトタイプを作成中。

サーバサイドはCakePHPでやろうとして、フロントはどうしようかなと。jQuery

いやいや、大きくなりそうな要件なので、テストやコードにルールを持たせたかったからフレームワーク使いましょ。じゃあAngularJSでということで、AngularJSを使うことになりました。(ほぼ私の独断と偏見)

まず選んだ人間の知識がないと引き継ぐことも教えることもできないので、とりあえずは色々チュートリアル、簡単なツール作成とかしてみましたが。。。

いやぁハマるハマるハマる。どろ沼ですよ。底なし沼ですよ。

「やっぱりjQueryでやろうかな。。。」と何度か諦めようとしていましたが、英語の記事を頑張って読んだり、仕事中にもAngularJSの記事をひたすら見ていたこともあり、少しずつ解決できるようになってきました。

おもいっきり使えるようにはなっていませんが、とりあえず先週の振り返りも合わせて記事とやったことのメモ。

AngularJSの考え方(?)

そもそもこのフレームワークってどう動いているのか、どんなことに便利なのか、どう組み立てたらいいのか全くわからなかったときに参考になった記事。図もあるので、わかりやすいです。

qiita.com

これもよかった。

qiita.com

AngularJSのほとんどのチュートリアルってすぐControllerを太らせるやり方が多かったけど、一応本家のチュートリアルにはちゃんと分けようみたいな概念的なページはある。

AngularJS

Controller間での状態の共有

qiita.com

Serviceのvalueメソッドとか使うといいんじゃないかなと思っていましたが、うまくいかず。。。しかしFactoryにすると何故かうまくいきました。。。

www.aipacommander.com

値&状態はservice、htmlはcomponent(directive)、モデルの設定、処理のバインドはcontroller、ビジネスロジックはserviceで

AngularJS1.5からcomponentってメソッドが追加されたとのこと。んで、それを使ったらゆくゆくデファクトになりそうなAngular2への以降が楽になるそうです。

ので、積極的に使おうと書いてみましたが、なにこれ?directiveの代わりでいいのかな・・・? あんまり自信はない。

    /**
     * Components
     */
    angular.module('component.components', [])

        .component('inputText', {
            bindings: {
                name: '='
            },
            template:
                '<div ng-show="$ctrl.flag">' +
                '   <label for="test">テストテキスト</label>' +
                '   <input ng-model="text" type="text" name="test">' +
                '   <button type="button" ng-click="$ctrl.submit()">登録</button>' +
                '</div>',
            controller: 'inputTextController'
        })

watchは少ないほうがいい

やっぱり多いとパフォーマンス悪いのね。jQueryみたいに$.on連発は注意すべし。

AngularJSの$watch登録数が60,000だった - @yoshiko_pg

controllerで親controllerのモデルを参照したい

$scope.$parent.parentControllerName.modelNameって感じでアクセスできた。

stackoverflow.com

<input type="hidden">で、ng-modelを使ってのbindingがうまくいかんかった

stackoverflow.com

You cannot use double binding with hidden field.

よくわからんが、うまくいかないらしい。

なので、ng-initを使って初期化してみました。CakePHP使っているからphpで書いています。

<?php
            echo $this->Form->input('id', [
                'type' => 'hidden',
                'ng-model' => 'id',
                'value' => $post->id,
                'ng-init' => 'id = ' . $post->id
            ]);

最終的にはこうなる。

<input type="hidden" name="id" ng-model="app.postId" ng-init="app.postId = 3" id="id" value="3" class="ng-pristine ng-untouched ng-valid ng-not-empty">

これでviewから値をbindすることができた。

ちなみに理由はこっちにあるらしいけど、あとで読む。

github.com

色々なAngularJSのコードを参考にした

これは別にハマった話ではないですが、学習するなら実際ビジネスで動作しているソースが参考になると思っていて、さらにAngularJSはJavaScriptフレームワークなので、ブラウザで参照できんじゃん!ってことで、AngularJSで実際動いてるサイトを探してみました。

github.com

こっちはAngular2が多いですが、こっちも参考になると思います。

www.angularattack.com

感想

1週間前は全くもってうまくいかなかったけど、なんとか形になってきた。もっと色々やった感はあるけど。

今度はAjaxとか使ってサーバとのデータのやり取りの処理やらアニメーションにチャレンジしなきゃ。