2.3.10(p34)までの内容。本書の内容を丸写ししているわけでなく、いくつかのコードを一纏めにしたりアレンジを加えたりしている。そのため少し見えづらいところも。
一般的なAngularJSの構造。
<html ng-app="myApp"> <!-- 名前を付けるのを忘れずに -->
<body ng-controller="TextController">
<p>{{someText.message}}</p> <!-- view1 -->
<p ng-bind="someText.message"></p> <!-- view2 こちらでも表示可能 -->
<!--
[view 1の問題]
angluar.jsが読み込まれるまで "{{someText.message}}" という文字列が表示されることになる
-->
<!-- CDN(コンテンツ配信ネットワーク)経由 -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js">
</script>
<!--
[CDNのメリット]
1. 高速なGoogleのサーバから読み込める
2. アプリケーション間にまたがってスクリプトをキャッシュできる
-> angularを扱うアプリが複数あったとしても, 同じURIから取得するから読み込みは1度のみ
-->
<script>
// moduleの定義. 第二引数は何だろう?
var myAppModule = angular.module("myApp", []);
// moduleにcontrollerを定義
// グローバル変数の汚染を防ぐメリットがある
myAppModule.controller("TextController", function($scope) { // controller
var someText = {}; // model
someText.message = "旅の始まりです";
$scope.someText = someText;
});
</script>
</body>
</html>
テンプレート、データバインディング。属性"ng-xxxxx"でイベントを付与したり、valueやclassを変更したりできる。
<html ng-app="myApp">
<body>
<form ng-controller="StartUpController">
<!-- 見込み1: <input ng-change="computeNeeded()" ng-model="funding.startingEstimate"><br>
-->
見込み2: <input ng-model="funding.startingEstimate"><br>
推奨額: <span ng-bind="funding.needed"></span><br>
<!-- クリック, ダブルクリックに対応するディレクティブ -->
<button ng-click="requestFunding()">出資を依頼する!</button><br>
<button ng-dblclick="reset()">リセット</button><br>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js">
</script>
<script>
var myAppModule = angular.module("myApp", []);
myAppModule.controller("StartUpController", function($scope) {
$scope.funding = { startingEstimate : 0 };
// 見込み1の場合
// <input>の中身が変わった時に'のみ', 以下のfunction()が実行
// $scope.computeNeeded = function() {
// $scope.funding.needed = $scope.funding.startingEstimate * 10;
// };
// 見込み2の場合
// $scope.$watchでfunction.startingEstimateを監視対象へ
// funding.startingEstimateが変更する度に, computeNeeded()が走る
var computeNeeded = function() {
$scope.funding.needed = $scope.funding.startingEstimate * 10;
};
$scope.$watch("funding.startingEstimate", computeNeeded);
$scope.requestFunding = function() {
alert("もっと顧客を増やしてからにしてください");
};
// 見込み1の場合は, 推奨額はゼロにならないことに注意
$scope.reset = function() {
$scope.funding.startingEstimate = 0;
};
});
</script>
</body>
</html>
見込みに数字を入れると自動的に推奨額が算出される。ボタンの動作はコードを見れば明らか。
<html ng-app="myApp">
<style>
<!--
.before_add {
color : #aaaaff;
}
.after_add {
color : #ffaaaa;
}
-->
</style>
<body>
<div ng-controller="StudentListController">
<ul ng-show="listState.show">
<!-- 繰り返し -->
<li ng-repeat="student in students">
<!-- $index は0スタート -->
{{$index + 1}} : <a href="/student/view/{{student.id}}">{{student.name}}</a>,
<!-- 動的クラス変更 (ng-classではなく, classのままだと動的にならない) -->
<span ng-class="{ before_add : !isAdd, after_add : isAdd }">
<!-- $first, $middle, $last は真偽値($middleはリストの最初と最後以外でtrue -->
first : {{$first}},
middle : {{$middle}},
last : {{$last}}
</span>
</li>
<button ng-click="insertTom()">追加</button>
</ul>
<button ng-click="toggleList()">リストをトグル</button>
<!--
[補足]
src, hrefを動的に変更するには, classのときと同様にそれぞれng-src, ng-hrefを使用する.
<img ng-src="/xxx/yyy/id={{hoge_id}}">
<a ng-href="/xxx/yyy/id={{hoge_id}}">リンク</a>
-->
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js">
</script>
<script>
var students = [
{ name : "メアリー", id : 1 },
{ name : "ジャック", id : 101 },
{ name : "マイケル", id : 55 }
]
var myAppModule = angular.module("myApp", []);
myAppModule.controller("StudentListController", function($scope) {
$scope.students = students;
$scope.insertTom = function() {
$scope.students.splice(1, 0, { name : "トム", id : 492 });
$scope.isAdd = true;
};
$scope.listState = { show : false };
$scope.toggleList = function() {
$scope.listState.show = !$scope.listState.show;
};
});
</script>
</body>
</html>
最初は listState.show が false のために ul は非表示。
表示。
<span ng-class="{ before_add : !isAdd, after_add : isAdd }">
が効いていて first, middle, lastに css が適用されている。また、それぞれのリンク先は<a href="/student/view/{{student.id}}">
で指定した通り、モデルのidになっている。
追加を押すとトム追加。
isAdd = true により class が after_add へ。適用される css が変化。
特に制御しているわけではないので、ボタンを押す度にトムが追加される。
JavaScriptのメソッドsplice()で配列を操作すれば、生徒を追加したり削除したりできる。
どうしてこのような書き方をするのか?
↓
Unobtrusive JavaScript(控えめなJavaScript)
・HTMLとJavaScriptの分離
・JavaScriptのコード散乱を防ぐ。そのためのMVC。