HOME ≫ 備忘帳 ≫ AngularJSチュートリアル ≫
2.Angularテンプレート
<戻る(1.静的テンプレート) 次へ(3.繰り返し要素のフィルタ)>
ではいよいよ、AngularJSによる動的ページを作りましょう。
同時に、コードのテストも追加します。
アプリのコードを構造化する手法はいろいろありますが、AngularJSでは「モデル・ビュー・コントローラー(MVC)」というデザインパターンの使用を推奨しています。
変更済みのファイル一式は、git checkout -f step-2で取得できます。
ビューとテンプレート
Angularでは、モデルを変更すれば、関連付けられているビュー(HTMLテンプレート)にも反映されます。
app/index.html の内容の主要部分は以下の通りです。
<!-- 使うモジュールを宣言 -->
<html ng-app="phonecatApp">
<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="js/controllers.js"></script>
</head>
<!-- この内側に適用するコントローラを宣言 -->
<body ng-controller="PhoneListCtrl">
<ul>
<!-- 繰り返し要素 -->
<li ng-repeat="phone in phones">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
</body>
</html>
前のステップでハードコーディングされていたスマホリストを、ngRepeatディレクティブと2つのAngular式で置き換えています。
<html ng-app="phonecatApp">
phonecatApp というモジュールを使う宣言。
phonecatAppモジュールはjs/controller.jsにあります。モジュール内には、PhoneListCtrlがあります。<body ng-controller="PhoneListCtrl">
PhoneListCtrl というコントローラをbodyに関連付けしています。<li ng-repeat="phone in phones">
(PhoneListCtrl内の)phones というリストデータの一つ一つについて、<li>ブロックを繰り返し表示します。評価中のデータをphoneという変数で参照できるようにます。{{phone.name}}と{{phone.snippet}}
バインディング。その式を評価した値に差し替えられます。
モデルとコントローラー
app/js/controllers.js の内容は以下の通りです。
// 'phonecatApp'という名前のモジュールを宣言、変数phonecatAppに格納
var phonecatApp = angular.module('phonecatApp', []);
// モジュールに'PhoneListCtrl'というコントローラを登録。
phonecatApp.controller('PhoneListCtrl', function($scope) {
// phonesというデータモデルを準備
$scope.phones = [
{'name': 'Nexus S',
'snippet': 'Fast just got faster with Nexus S.'},
{'name': 'Motorola XOOM™ with Wi-Fi',
'snippet': 'The Next, Next Generation tablet.'},
{'name': 'MOTOROLA XOOM™',
'snippet': 'The Next, Next Generation tablet.'}
];
});
- コントローラ PhoneListCtrl は、スマホデータを $scope に格納しています。
このスコープは、最初にアプリが定義された時に作られるルートスコープのプロトタイプ子孫です。 - コントローラの有効範囲内では、$scopeを利用できます。
スコープ
Angularのスコープのコンセプトは重要です。
スコープは、テンプレート(ビュー)、モデル、コントローラが一緒に働くための接着剤のようなものです。スコープは、モデルとビューを同期させつつも分離した状態に保つために、テンプレート(に含まれる情報)、データモデル、コントローラと共にスコープを使います。
Angulerのスコープについて詳しくは、angular scope documentation を参照してください。
テスト
コントローラをビューと分離すれば、ビュー(画面)がなくてもコードだけでテストができます。
コントローラーがグローバル名前空間にある場合、空のscopeオブジェクトでインスタンス化できます。
describe('PhoneListCtrl', function(){
it('phonesモデル内にスマホデータ3つ必要', function() {
var scope = {}, // 単純な空オブジェクト
ctrl = new PhoneListCtrl(scope);
expect(scope.phones.length).toBe(3);
});
});
上のテストでは、PhoneListCtrl をインスタンス化し、phonesという配列のプロパティがあるか、そこに3つの要素が含まれているかを確認しています。
グローバルではないコントローラのテスト
このチュートリアルでは、コントローラはphonecatAppモジュール内にあります。
このように、コントローラがグローバルな名前空間になくても大丈夫です。
test/unit/controllersSpec.js の内容は以下の通りです。
describe('PhoneListCtrl', function(){
beforeEach(module('phonecatApp'));
it('phonesモデル内にスマホデータ3つ必要', inject(function($controller) {
var scope = {}, // 単純な空オブジェクト
ctrl = $controler('PhoneListCtrl', {$scope:scope});
expect(scope.phones.length).toBe(3);
}));
});
beforeEachで、テスト前phonecatAppを読み込むよう指示しています。- Angularが用意している
$controllerサービスを、テスト関数に注入injectします。 - PhoneListCtrl のインスタンスを作る時に、$controller を使います。
テストの実行方法
ユニットテストにはKarmaを使う設定になっています。Karmaがインストールされていない場合は、先にインストールしてください。
テストを実行するには、npm testコマンドを使います。
- Karmaは自動的に、ChromeとFirefoxの新規ウィンドウを開きます。Karmaはこのウィンドウでテストを実行します。
- ChromeかFirefoxのどちらかしかない場合は、テスト前にtest/karma.conf.jsファイルのbrowsersの部分を書き換えてください。
- コマンドプロンプト等、npm testコマンドを使ったターミナルウィンドウに、テスト結果が表示されます。
- バックグラウンドで起動したままにしておけば、開発中のコードやテスト、test.jsファイルを更新するたびに、自動的に再テストされます。
Karmaが開いたウィンドウは最小化しないでください。
OSによっては、最小化したブラウザへのメモリ割り当てが非常に少なくなって、テスト実行がとても遅くなります。
<戻る(1.静的テンプレート) 次へ(3.繰り返し要素のフィルタ)>
最終更新日:2015/12/22
[ ページ先頭へ ]