KN_minami_BLOG

方向性がよくわからない

初めてのクライアントサイドでAngularJSとMVCパターンの話

 

この記事はAizu Advent Calendar 201619日目の記事です。

前の人は@noah_orbergさん、次の人は@ababup1192さんです。

はじめに

 

いつもはサーバーサイドを中心に勉強しているんですが、最近クライアントサイドをAngularJSで書くことがあったので、勉強がてらそれら周りついて書きたい。

なので、書きます。

 

今回は、基本的なモジュールや機能をざっとまとめつつ、AngularJSの特徴でもあるMVCパターンについて書いていきます。

 

間違いがあったりするかと思うので、そこは指摘してもらえたら嬉しいです?

 

AngularJSの話

 

f:id:nktafuse:20161219132715j:plain

 

 

 

AngularJSは、JavaScriptフレームワークの一つで、CRUD系のWebアプリケーション開発向きです。例えば、管理画面など変更があるところ。

フルスタックが魅力でフロントエンド開発において、大方の機能が使えます。

なので、環境構築で時間をとられることが少ない。便利!

特徴としては、

  • 双方向データバインディング
  • HTMLベースのテンプレート機能
  • シンプルなルーティング機能
  • ビルトインディレクティブ
  • セキュリティ対策

などなどがあり、とても高機能です。

 

ちなみにAngular 2なるものが出てきましたが、それはTypeScriptのフレームワーク

そっちも機会があればぜひ触ってみたい。。 

 

双方向データバインディング

双方向データバインディングとは、データとUIを双方向に結びつけて、UIとデータに相互性をもたせます。

モジュール

モジュールはアプリケーションが必要としているパーツの情報を持ったオブジェクトです。

なので、AngularJSでアプリを開発にするにあたって最初に行うのがmoduleを作ることで、それにはangular.moduleメソッドを使って以下のようにかきます。

 

var appModule = angular.module("appModule",[]);

第一引数にモジュールの名前、第二引数以降には依存するモジュールを書いていく。

ちなみに、作成するときは第二引数がいらなくても省略できないらしい。

 

 

ビルトインディレクティブ

ビルトインディレクティブとは、いわゆるAngularJSにおけるHTML拡張のことで、基本的に ”ng-” の形で定義されてそれがなんと、70個ほどあるそうです。(自分はちゃんと把握していません。。)

そこで、今回は2つほど紹介します。

ngRepeat

ngRepeatディレクティブは、コレクションから各項目のテンプレートをインスタンス化します。

 

構文例

<li ng-repeat="{item in items}">item:{{item}}</li>

itemsの要素itemをループを回して表示するイメージです。

また、$indexなどでループの回数など回数関係の値の取得も可能です。

 

ngController

ngControllerディレクティブは、ビューにコントローラーのクラスを割り当てます。

構文例

<div ng-Controller="myConroller"></div>

divの中にControllerの要素となるものをいれてControllerによって操作できるようにします。

 

以上のように高機能なHTML拡張が沢山あります。

 

ルーティング 

ルーティングは、Single Page Applicationを実装する上で重要な機能ですが、AngularJSでは簡単に実装できます。

 

下にroute.jsとしてtop.htmlとhoge.htmlとpiyo.htmlを設定するコード書いていきます。

 

angular.module("appModule",["ngRoute","ngAnimate"])
 .confing(function($routeProvider){
  $routeProvider
  .when("/top",{
    templateurl:"top.html"
   })
   .when("/hoge",{
    template:"hoge.html"
    })
   when.("/piyo",{
   template:"piyo.html"<
   })
   .otherwise({
    redirectTo:"/top"
   })
});

 

上から順に説明すると

一行目でmoduleの定義とngRouteとngAnimateを呼び出しています。

二、三行目はconfigサービスと$routeProviderでurlと読み込み先を紐付けています。

 

whenはrouteの追加。

otherwiseでは、ルートの定義がない場合のルーティングを定義しています。

 

他にもう少しあるのですが(Controllerの設定や、ngRouteとんngAnimateをheadで読み込ませるとか)基本的なルーティングは以上のように簡単に実装できます。

 

 

AngularJSの機能をいくつか見てきましたが、これはほんとごく一部で他にもいろいろあります。

ぜひ触ってみてください。

 

MVCの話

 

f:id:nktafuse:20161219133305j:plain

 

 

angularJSは、MVW(Model View Whatever)パターンのフレームワークであり、MVC(Model View Contrller)パターンであるとも言えます。

今までMVCパターンをなあなあな感じに把握していたのですが、調べてみると色々面白かったです。

なのでまあ、色々な考え方あるのだとは思いますが、MVCを上手に使う為の今の自分の認識を書きたいと思います。

 

では、MVCそれぞれの役割についてControllerを中心に見ていきます。

 

 

Controller

 

ここで、Controllerを使う場合の気をつけたい点を一つ。

 

Controllerは、肥大化させるべきではありません。

そう、いわゆるFat Controllerってやつです。

 

しかし、なぜControlllerは肥大化させるべきではないのでしょうか?

理由は単純で、Controllerへかくのは変更処理に対して弱くなりやすくなるからです。

基本的にControllerはViewの設計に引きずられてしまい、Viewの影響を受けやすいわけで。

 

Fat Controllerを作らない為に気をつけたいのは、ビジネスロジックをControllerに書かないことです。全てModelに任せてしまいましょう。viewやControllerに変更があってもModelには影響が少ないからです。

なので、基本的にControllerはviewとModelを操作することに限るべきです。

つまり、バインディングとイベントハンドリングの機能にしぼるのがいいと思います。

 

また、ModelとControllerのやりとりを一通的にすべきです。

どういうことかというと、Controllerが命令してそれに対してModelが答えるというスタイルをできるだけ心がけるべきということです。

そうすることにより、ビジネスロジックをControllerに書くことが圧倒的に減ると思います。

 

ゲーム機のコントローラーもプレイヤーとゲーム機本体の仲介役でしかないですしね。

そんなイメージでControllerを使ったほうがいいのかと思います。

 

f:id:nktafuse:20161219185206j:plain

 

Model

 

AngluarJSではserviceやfactory、valueなどというサービスを作ることができます。

 

service

serviceの構文例

 

angular.module.service("name", ["$window",function($window) { ...
}]);

* nameにserivceの名前、それ以降に依存サービスや関数を配列に入れる。

 

serviceは共有したいオブジェクトのコンストラクタを登録し、newインスタンスが生成します。

そのためプリミティブ型を提供できません。

なのでJavaScriptクラスを作る時に使うといいと思います。

 

factory

factoryの構文例

 

angular.module.factory("name",["$interval",function($interval) { ...
}]);

*nameにfactoryの名前、それ以降に依存サービスや関数を配列に入れる。

 

serviceにたいしてfactoryは、共有したい関数、値、オブジェクトを返します。

また、プリミティブ型を提供して、newでインスタンスしたくない時に使えます。

なので、関数、値を使いたい時に有効です。

 

以上の他にもvalueなど他のサービスがあります。

自分はserviceよりfactoryを多く使った。。。

 

 以上のようなサービスはControllerの配列に入れて、依存サービスとして利用できます。

また、Modelは一つのサービスにたくさんの処理を書くのではなく、役割や処理ごとに分割して作りましょう。そうすることによって、より変更などに強くなれます。

それらを利用して、つねにcontrollerをスリムに作ることを意識するのが大事です。

 

ここで、処理が多くなればどっちにしろModelも肥大化してしまうのでは?

という考えもでてくると思うのですが、それに関してはControllerが肥大化してしまうよりはModelが肥大化するほうがまだいいのです。

なぜかというと、ModelはViewの変更の影響がControllerよりは少ないからです。

なので、( Fat Model ) ,Skinny Controllerを意識しましょう。

 

 

View

  • Modelの状態を参照して表示する

viewが参照すべきなのは、ModelからでありControllerではありません。

なので、viewは表示と更新、ユーザーの入力をコントローラーに渡すことに専念させましょう。

 

 

以上のように、それぞれの役割を意識して書くだけでスリムでいいMVCがかけると思います。

 

参考情報 

この記事を書くにあたって以下のページを参考にさせてもらっています。

ぜひ見てみてください。

おわりに

 初めてクライアントサイドを書いたので全然知らないんですが、AngularJSなかなかいいです。他のフレームワークと比べるとフルスタックなんで、学習コストは高くなってしまいますが、(加えて、フレームワーク側の挙動が複雑でデバックが大変だったり)人気なのがなんとなくわかりました。次はAngular2も触ってみたい。

 

みなさんすごくつよい記事を書いているのに、全くコードを書いてないし説明がなってないし辛い。。

来年のAACはいい記事書けるように頑張りたい。。はい。。

 

では!