AngularJS TIPS
モデルをテキストボックスなどのフォーム要素にバインドするには?(ng-model)
ビューの変更をモデルに反映させ、逆にモデルの変更をビューに反映させる、AngularJSの双方向データバインディングの基本を解説する。デフォルト値の設定方法も説明。
AngularJSの特徴的な機能の1つとして、双方向データバインディングが挙げられます。
データバインディングとは、JavaScriptのオブジェクト(モデル)をHTMLテンプレート(ビュー)に結び付けるための機能。その考え方そのものは、古典的なテンプレートエンジンから存在した仕組みです。
しかし、旧来のテンプレートエンジンでは、ビューにモデルを一度だけ引き渡すだけで、ビューの変更(例えばユーザーからの入力された内容)をモデルに書き戻すことはもちろん、以降のモデルの変更をビューに反映することはありません。一度、バインドした後、モデルとビューを同期するのはアプリケーションの責任なのです。このようなバインドの仕組みを、片方向データバインディングと呼びます。
一方、AngularJSのそれは、双方向データバインディングと呼ばれます。いったん、ビュー/モデルをひも付けた後は、ビューの変更はモデルに反映され、モデルの変更もまたビューに反映されます。ビュー/モデルの両者が常に同期されていることを、(アプリケーションではなく)フレームワークとして保証してくれるわけです。これによって、さまざまな処理の結果をページに反映する処理を、半自動化できるというメリットがあります。
双方向データバインディングの基本
以下に、具体的なサンプルを見てみましょう。以下のコードは、テキストボックスに入力された名前に応じて、「こんにちは、●○さん!」というメッセージを表示する例です。
<!DOCTYPE html>
<html ng-app>
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body>
<form>
<label for="name">名前:</label>
<!--1テキストボックスnameに対して、nameプロパティをひも付け-->
<input id="name" name="name" type="text" ng-model="name" />
<!--2nameプロパティを元に挨拶メッセージを生成-->
<div>{{"こんにちは、" + name + "さん!"}}</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
</body>
</html>
|
<input>/<select>/<textarea>などの要素をモデル(=スコープオブジェクトのプロパティ)にひも付けるには、ng-model
属性でバインドすべきプロパティを指定するだけです(1)。これによって、テキストボックスに入力された値に応じてname
プロパティの値も書き変わることになります。
このとき、2もエクスプレッション構文によってname
プロパティがひも付いていますので(正確にはname
プロパティを含んだ文字列連結式をひも付けていますので)、プロパティ値の変化に応じて、2の値が「こんにちは、●○さん!」のように変化するわけです。
データをページに反映するために一切のコードを記述する必要がない点、テキストボックスの値を何度変えても12の両者が同期される点を確認してください。
[Note]バインドを抑制するには?
ちなみに、{{...}}
をそのまま文字列として出力したい(=エクスプレッション式として認識させたくない)場合には、ng-non-bindable
属性を利用します。
<div ng-non-bindable>{{"こんにちは、" + name + "さん!"}}</div>
|
テキストボックスにデフォルト値を与える
ng-model
属性でモデルをひも付けた場合、<input>
要素にvalue
属性を付与してもテキストボックスにはデフォルト値は表示されません。ng-model
属性によって、テキストボックスの値はモデルの値と同期しているからです。
よって、テキストボックスにデフォルト値を与えるには、以下のようにコントローラーからスコープオブジェクトのプロパティを設定してやります。
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body>
<form ng-controller="myController">
<label for="name">名前:</label>
<input id="name" name="name" type="text" ng-model="name" />
<div>{{"こんにちは、" + name + "さん!"}}</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script>
// myAppモジュールにmyControllerコントローラーを登録
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) {
// テキストボックスにデフォルト値を与える
$scope.name = '権兵衛';
}]);
</script>
</body>
</html>
|
処理対象:{{プロパティ名}} カテゴリ:式(Expressions)
API:ngModel(ng-model) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
API:ngNonBindable(ng-non-bindable) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
※以下では、本稿の前後を合わせて5回分(第3回~第7回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
3. AngularJSでコントローラーを定義するには?
AngularJSアプリの最も基本的な構成要素である「コントローラー」の基礎として、コントローラー経由でスコープを準備し、テンプレートに反映させる方法を説明する。
5. 【現在、表示中】≫ モデルをテキストボックスなどのフォーム要素にバインドするには?(ng-model)
ビューの変更をモデルに反映させ、逆にモデルの変更をビューに反映させる、AngularJSの双方向データバインディングの基本を解説する。デフォルト値の設定方法も説明。
6. モデルをビューにバインドするには?(ng-bind/ng-cloak)
エクスプレッションが一瞬表示されてしまう不具合を解消して、AngularJSの双方向データバインディングを実現する方法を説明する。
7. ビューにHTML文書をバインドするには?(ng-bind-html)
文字列をデータバインドした際に、標準で実施されるサニタイズ処理について紹介。また、サニタイズせずにHTMLのままのビューに反映させる方法も説明する。