アプリケーション全体の枠組みの作成
AngularJSではモジュールという単位で機能のグループ管理を行っています。モジュールを作成するには、リスト1のようにangular.module関数を使って作成します。第1引数はモジュール名になり、HTMLのテンプレートで使用します。
var TodoModule = angular.module("todoModule",[]); // (1) モジュールの作成
また、作成したTodoModuleという変数には、この後、コントローラなどを追加していくために必要な変数です。第2引数は、依存するモジュールを指定するのですが、今回はモジュールが1つだけで、依存するモジュールはないので、空の配列である"[]"を指定します。何も指定しないとエラーになりますので注意して下さい。
続いて、全体の枠組みのHTMLをリスト2のように作成します。まずは、先ほど作成したモジュールを使用するための指定を(1)のように記述します。
これだけでもAngularJSが動作しているアプリケーションに変わりはありません。まずは、この状態で一度実行してみて、エラーが発生しないことを確認してみると良いでしょう。
<!DOCTYPE html>
<html>
<head lang="ja">
<meta charset="UTF-8">
<title>AngularJS:TODO 管理</title>
<!-- 共通のヘッダ -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script type="text/javascript" src="vendors/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="vendors/angular.js"></script>
<script type="text/javascript" src="vendors/bootstrap/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="vendors/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="vendors/bootstrap/css/bootstrap-theme.min.css">
<!-- 今回のサンプルコード -->
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
</head>
<body ng-app="todoModule"> <!-- (1) モジュールを読みこむ -->
<!-- 中身を後で作る -->
</body>
</html>
リスト2の(1)では、"ng-app"という属性を用いてモジュールを指定しましたが、AngularJSでは、"ng-"から始まる属性を使って、AngularJS上のコードと連携を行います。
AngularJSでは、このような属性、またタグを新たに作成することができ、それらを「ディレクティブ」と呼んでいます。
また、あらかじめ用意されている属性は"ng-xxxx"のように"ng-"から始まっており、それらは、API Referenceで確認することができます。
それぞれのディレクティブには、タグ形式、属性形式、そして最初はあまり使うことはないのですがコメント形式があります。
また、名称は属性として指定する場合に表記方法が多少異なり、例えば"ngApp"という名前のディレクティブは"ng-app"という属性で指定します。
ページ制御の為のコントローラとテンプレートの作成
続いて、ページを制御する為のコントローラをリスト3のように作成を作成します。「コントローラ」とは、HTML側で指定する"ng-controller"属性を指定した要素配下を管理する為の処理となります。
(function(module){ // (1) 処理を即時関数内に入れる
'use strict'; // (2) Strictモードを指定する
module.controller('pageController',function($scope){ // (3) コントローラを作成
// (4) 表示する要素の管理
$scope.show = {
list : true,
add : false,
info : false
};
}
}(TodoModule)); // (5) モジュール変数を引数に設定
コントローラを作成する際には、処理は(1)のように即時関数内に入れるようにします。これは、AngularJSを利用する際に必要な処理ではありませんが、2つの意味があります。1つめは、(2)のようにStrictモードをこの処理のみに指定できるようにします。そして、もう一つ目はモジュール変数との結合を弱くすることです。モジュールの為に作成した変数が変わった際にも定義自体を変える必要はなく、(5)の引数の部分だけの変更で対応できます。
即時関数とは、JavaScriptが関数という単位でスコープが決まる性質を利用し、その場で実行する処理を関数内に入れることで別のスコープとして処理をするためのテクニックです。
また、Strictモードとは、JavaScriptのルーズな部分、例えば、変数の宣言をしない変数の利用などがあったときに、その検知を行いエラーを発生させる機能です。
Strictモードは、スクリプトの先頭や関数の先頭に記述することでそのスコープ内での検知を有効にすることができるのですが、スクリプト全体に影響させることは、他のコード等も動作しなくなる恐れがあるために、即時関数を使ってスコープを限定しその記述内でのみ有効にします。
この2つのテクニックは一緒に使われることが多いために、セットで覚えておくと便利です。
コントローラの定義は(3)のようにmodule.controller関数を用いて作成します。第1引数はngControllerディレクティブで指定する名前を、そして、第2引数には指定したタグ内の処理をするための関数を定義します。
定義する関数の引数には特別なルールがあります。このあたりが、JavaScriptとしては特殊な構造になっていて、わかりにくいと感じるかもしれませんが、AngularJSの特徴でもあり、便利な機能になっています。通常、引数というのは関数内で使う変数を指定する為の便宜上の任意の名称でよいのですが、AngularJSの場合には変数名自体が意味をもっており、その引数の変数名によって自動的に機能を使い分けることができます。
HTML内の表示を制御したい場合には、"$scope"という引数という変数を引数に指定します。この"$scope"という変数は、指定したタグ内の要素を管理する為のオブジェクトになります。
これ以外にも、AngularJSであらかじめ用意されている使える引数があります。完成したサンプルコードでは別の引数も使っていますので、次回に引数の使い方についてはさらに詳しく説明します。
続いて、作成した3つのページ全体を管理する為のHTMLをリスト4のように変更します。
<body ng-app="todoModule" ng-controller="pageController"> <!-- (1) ng-controllerの指定 -->
<!-- ヘッダ部分 -->
<!-- タスク一覧画面 -->
<div ng-show="show.list"> <!-- (2) ng-show での表示の切り替え -->
</div>
<!-- タスク追加画面 -->
<div ng-show="show.add">
</div>
<!-- タスク参照画面 -->
<div ng-show="show.info">
</div>
<!-- フッタ部分 -->
</body>
また、ここで使用するディレクティブは表2となります。
| ディレクティブ名 | 指定する属性 | 説明 |
|---|---|---|
| ngController | ng-controller | 定義したコントローラの指定を行います。 |
| ngShow | ng-show | 値に論理値を指定し、trueの場合にはその要素を表示、falseの場合には非表示になります。 |
まずは、(1)のように"ng-controller"属性で先ほど作成したコントローラ名を指定します。また、ページの切り替えは、(2)のように"ng-show"属性で指定します。
"ng-show"属性で指定した"show.list"という指定は、"$scope.show.list"という変数に対してアクセスしていることと同様であり、(4)のように"$scope.show.list"のみにtrueを指定することで、一覧ページのみの表示ができるようになります。つまり、表示するページを切り替える際には、(4)の"$scope.show"のいずれにtrueを指定するかで、ページの切り替えが行えます。
ただし、通常の利用では3つのページのいずれかの表示になるのでswitchの機能である"ngSwitch"を利用しますが、今回は単純な表示・非表示の切り替えである"ngShow"を使っています。
