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
[ ページ先頭へ ]