AngularJSのひと通り動作させるためにやったこと
AngularJSのひと通り動作させるためにやったことをメモっときます。
前提
この作業メモには以下の前提があります。- レイアウトにはTilesを使っています。
- Springframework, mavenを使っています。
- AngularJSを使うためにはこの辺の技術は関係ありませんが、自分用のメモのため記載が登場します。
- 筆者はJavaScript初心者のため、有識者にとって見苦しい記載/コードがあるかもしれません(;´Д`)
必要な知識
とりあえず気にしておくこと- AngularJSはJavaScriptでMVCを実現するためのフレームワーク
- これまではサーバサイドでMVCが実現されることが多かったですが、それをブラウザ側(JavaScript)で実現できます。
- ブラウザ側が高機能になってきており、それに伴いクライアントサイドが複雑化してきている。そのためモジュール化やMVC化が求められているというのが背景らしいです。
- 各処理の単位をMVCで書けるため、ControllerとSericeモジュールは意識して定義する必要がある。
やりたいこと
- サーバ側APIからユーザ一覧情報を取得して、ユーザ情報を画面に表示する。
- 画面例
全体的なの流れ
- モジュールを作成します。
- そのモジュールにServiceとControllerを登録していきます。
- 画面とControllerを紐付けます。
以下の記載には別途最初にレイアウト関連の記載があります。
作業メモ
Springやビルド関連
全てJavaScriptで閉じているため、特に変更なし(spring-context.xnkやpom.xml)レイアウト関連(Tiles)
ControllerモジュールとServiceモジュールをロードするために画面設定に修正する。- レイアウトファイル(layout.jsp)
- ng-appはAngularJSの機能を使うために必要な定義。定義したタグ内にAngularJSが適用される。とりあえずはhtmlタグに定義しておけば問題ない。名前について後述。
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <html ng-app="sampleApp"> <head> <title><tiles:getAsString name="title"/></title> <tiles:insertAttribute name="header" /> <tiles:insertAttribute name="commonScript" /> <tiles:insertAttribute name="services" /> #Serviceモジュールを定義するための領域確保 </head> <body> <tiles:insertAttribute name="body" /> <tiles:insertAttribute name="footer" /> <tiles:insertAttribute name="controllers" /> #Controllerモジュールを定義するための領域確保 </body> </html>
AngularJS関連
- AngularJS取り込み
- AngularJSを使うために関連モジュールを取り込むために以下追加
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
- Tiles定義ファイル(definition.xml)
- 上記で設定した属性に定義ファイルを割り当てる。
- Controllerは各ページごとに違うと想定して、基底ページでは定義しない(空文字指定)。今のところ。
(略) <tiles-definitions> <definition name="baseLayout" template="/WEB-INF/views/common/layout.jsp"> <put-attribute name="header" value="/WEB-INF/views/common/header.jsp" /> <put-attribute name="commonScript" value="/WEB-INF/views/common/script.jsp" /> #Module割り当て(名前が良くない気がする(;´Д`)) <put-attribute name="services" value="/WEB-INF/views/common/services.jsp" /> #Serviceモジュール割り当て <put-attribute name="controllers" value="" /> #Controllerモジュール割り当て。形だけ。 <put-attribute name="footer" value="/WEB-INF/views/common/footer.jsp" /> </definition> <definition name="user.list" extends="baseLayout"> <put-attribute name="title" value="User Management" /> <put-attribute name="body" value="/WEB-INF/views/user/body.jsp" /> <put-attribute name="controllers" value="/WEB-INF/views/user/controllers.jsp" /> #Controllerモジュール割り当て </definition> (略)
- モジュール作成
<script> angular.module('sampleApp', []); </script>
- Serviceモジュール作成
<script> var app = angular.module('sampleApp') app.service('userService', ['$rootScope', function ($rootScope) { this.getUsers = function () { $.ajax({ type: 'GET', url: '/sampleapp/api/users', dataType: 'json', success: function (json) { $rootScope.$broadcast('getUsersCompleted', json) } }); } }]); </script>
- Controllerモジュール作成
- 上記で定義したServiceを使うController
- 定義例:controllers.jsp
- ここでもModule作成は第2引数がないので、上記で作成した"sampleApp"が返ってくる。みんなそこにどんどん(ry
- 引数に"userService"を指定しているが、AngularJSが同名をもつモジュールをDIしてくれる(ここでは上記で定義したuserServiceが注入される)。
- 定義しているのは、変数(users)とか初期化用メソッド(init)、あとイベント検知のためのリスナー(?)登録。
- 基本的に$scopeに対して定義します。
- イベントを検知するためには、$onに対して行い、任意のキーワードを指定してListenします。
- この場合だと上記でuserServiceが"getUsersCompleted"に対してブロードキャストするため、ここで同じキーワードを指定することで検知できます。*2
<script> var app = angular.module('sampleApp') app.controller('userManagementController', ['$scope', 'userService', function ($scope, userService) { $scope.users = [] $scope.init = function () { userService.getUsers() } $scope.$on('getUsersCompleted', function (event, params) { $scope.$apply(function () { angular.copy(params, $scope.events); }); }); }]); </script>
- Viewに対してモジュール割り当て
- 今まで作成したモジュールをView(jspやhtml)に割り当てます。
- 本来ServiceモジュールはControllerモジュールから使われるはずなので、Viewに割り当てるのは、Controllerモジュールだけのはず(今回もそうです)。
- 定義例:body.jsp
- AngularJSはHTML拡張の側面が強いため、いろいろなタグを利用できる(ディレクティブと呼ぶ)。
- ng-controller:利用するControllerの宣言
- ng-init:Controllerの初期化処理。ここではuserManagementControllerで定義したinitを呼ぶようにしている。
- ng-repeat:for文に相当。ここでは、userManagementControllerで定義したusers変数を回している。
- {{ }}:式評価はこの表現で出来る。ここでは、user情報のnameの値は表示される。
- AngularJSはHTML拡張の側面が強いため、いろいろなタグを利用できる(ディレクティブと呼ぶ)。
- 今まで作成したモジュールをView(jspやhtml)に割り当てます。
<div ng-controller="userManagementController" ng-init="init()"> <div class="well" ng-repeat="user in users"> <li>ユーザ名:{{user.name}}<br> </div> </div>
所感
- いままでJavaScriptは関数たくさん書きまくって使いまわすようなC言語のような使い方しかしなかったので、今どきのやり方に触れられた気がします(*´Д`*)
- MVCとかDIとかはSpringFrameworkで使っていたので特に概念的なギャップはなく、スッと頭に入ってきました。あとはJavaScript/AngularJSの作法を学ぶ必要がある感じ。
- もっと使いこなしてきたら、新しい概念がどんどんでてきそう。
- あと他のJavaScriptフレームワークを知らないので、AngulerJS自体の評価はわかりません(;´Д`)
参考
- AngularJS — Superheroic JavaScript MVW Framework
- すぐできる AngularJS
- 作者: 池添明宏,金井健一,吉田徹生,丸山弘詩
- 出版社/メーカー: インプレス
- 発売日: 2014/09/05
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る