AngularJSのデータバインドについて
AngularJSのモデルとデータバインドについて、書きたいと思います。
AngularJSは、モデルのプロパティにINPUTやSELECTやRADIOなどのデータを
バインドすることができます。
AngularJSのモデルは、下のようなJSON形式になっています。
var webApp = angular.module('webApp', []); webApp.controller('controller', function($scope) { $scope.item = {'key' : 1, 'value' : 'item_1'}; });
このモデルをテンプレートで利用する為に、$scopeに設定することで、利用可能になります。
気をつけないといけないことは、前回と同じく、下の様に書くとバインドされません。
<input type="text" value="{{item.value}}"/>
バインドする為には、バインドさせたいものに対して、
属性として、ng-modelを使い、モデルのプロパティを指定するとデータをバインドさせることができます。
<!DOCTYPE html> <html lang="ja" ng-app="webApp"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <script src="./angular.min.js"></script> <script src="./controller.js"></script> </head> <body ng-controller="controller"> <!-- バインドさせたいモデルのプロパティを指定 --> <input type="text" name="item" ng-model="item.value"/> </body> </html>
これで、画面の値を変更すると、その変更がモデル反映されます。
また、HTMLのタグの種類により書き方が若干違います。
RADIOやCHECKBOXなどのタグが複数あるものは、
繰り返す必要があるので、ng-repeatとng-modelを使います。
モデルの定義は、下の様な感じです。
$scope.categoryList = [ {'key' : '1', 'label' : 'CATEGORY_A', 'value' : false}, {'key' : '2', 'label' : 'CATEGORY_B', 'value' : false}, {'key' : '3', 'label' : 'CATEGORY_C', 'value' : false} ];
テンプレート側は、ng-repeatを使って、
他の言語などのforeachみないな感じで、書くことができます。
また、バインドの方法は、通常と同じく、ng-modelでプロパティを指定するだけです。
テンプレートは、下の様な記述になります。
<label ng-repeat="category in categoryList"> <input type="checkbox" name="category" ng-model="category.value"/> {{category.label}} </label>
SELECTBOXも基本的に同じなんですが、
ng-repeatではなく、専用のものがあります(ng-repeatでも行けるけど)。
ng-optionsを使います。
モデルの定義は、下の様な感じです。
$scope.codeList = { 'value' : '', 'list' : [ {'key' : 100, 'label' : 'CODE_100'}, {'key' : 200, 'label' : 'CODE_200'}, {'key' : 300, 'label' : 'CODE_300'}, {'key' : 400, 'label' : 'CODE_400'} ] };
テンプレート側は、ng-optionsを使います。
ng-repeatと書き方が違い、キー as ラベル for 配列の形式で書きます。
また、バインドの方法は、通常と同じく、ng-modelでプロパティを指定するだけです。
テンプレートは、下の様な記述になります。
<select name="code" ng-model="codeList.value" ng-options="code.key as code.label for code in codeList.list"> <option value="">選択して下さい。</option> </select>
また、グルーピングにも対応していて、
その場合のモデルは、こんな感じです。
$scope.codeList = { 'value' : '', 'list' : [ {'group' : 'GROUP_A', 'key' : 100, 'label' : 'CODE_100'}, {'group' : 'GROUP_A', 'key' : 200, 'label' : 'CODE_200'}, {'group' : 'GROUP_B', 'key' : 300, 'label' : 'CODE_300'}, {'group' : 'GROUP_B', 'key' : 400, 'label' : 'CODE_400'} ] };
テンプレートの方もng-optionsの書き方が少し違い、
キー as ラベル group by グループ for 配列の形式で書きます。
<select name="code" ng-model="codeList.value" ng-options="code.key as code.label group by code.group for code in codeList.list"> <option value="">選択して下さい。</option> </select>
それと、ng-optionsの注意点ですが、生成されたHTMLを見るとわかるんですが、
optionのvalueが下の様に0からシーケンス値みたいに順番に設定されてしまいます。
<select name="code" ng-model="codeList.value" ng-options="code.key as code.label group for code in codeList.list"> <option value="" selected="selected">選択して下さい。</option> <option value="0">CODE_100</option> <option value="1">CODE_200</option> <option value="2">CODE_300</option> <option value="3">CODE_400</option> </select>
ただ、データバインドはうまく動いていて、初期値の設定なども問題ありませんが、
formのsubmitで、送信してしまうとのvalueの値がそのまま送信されるようで、
注意が必要です。
REST APIで、モデルをPOSTする分には、問題なさそうです。