Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

モデルをテキストボックスなどのフォーム要素にバインドするには?(ng-model)

2015年3月5日

ビューの変更をモデルに反映させ、逆にモデルの変更をビューに反映させる、AngularJSの双方向データバインディングの基本を解説する。デフォルト値の設定方法も説明。

  • このエントリーをはてなブックマークに追加

 AngularJSの特徴的な機能の1つとして、双方向データバインディングが挙げられます。

 データバインディングとは、JavaScriptのオブジェクト(モデル)をHTMLテンプレート(ビュー)に結び付けるための機能。その考え方そのものは、古典的なテンプレートエンジンから存在した仕組みです。

 しかし、旧来のテンプレートエンジンでは、ビューにモデルを一度だけ引き渡すだけで、ビューの変更(例えばユーザーからの入力された内容)をモデルに書き戻すことはもちろん、以降のモデルの変更をビューに反映することはありません。一度、バインドした後、モデルとビューを同期するのはアプリケーションの責任なのです。このようなバインドの仕組みを、片方向データバインディングと呼びます。

 一方、AngularJSのそれは、双方向データバインディングと呼ばれます。いったん、ビュー/モデルをひも付けた後は、ビューの変更はモデルに反映され、モデルの変更もまたビューに反映されます。ビュー/モデルの両者が常に同期されていることを、(アプリケーションではなく)フレームワークとして保証してくれるわけです。これによって、さまざまな処理の結果をページに反映する処理を、半自動化できるというメリットがあります。

双方向データバインディングの基本

 以下に、具体的なサンプルを見てみましょう。以下のコードは、テキストボックスに入力された名前に応じて、「こんにちは、●○さん!」というメッセージを表示する例です。

HTML
<!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>
双方向データバインディングの基本的な例(bind.html)
テキストボックスの値に応じて、挨拶メッセージを表示(1) テキストボックスの値に応じて、挨拶メッセージを表示(2)
テキストボックスの値に応じて、挨拶メッセージを表示

 <input>/<select>/<textarea>などの要素をモデル(=スコープオブジェクトのプロパティ)にひも付けるには、ng-model属性でバインドすべきプロパティを指定するだけです(1)。これによって、テキストボックスに入力された値に応じてnameプロパティの値も書き変わることになります。

 このとき、2もエクスプレッション構文によってnameプロパティがひも付いていますので(正確にはnameプロパティを含んだ文字列連結式をひも付けていますので)、プロパティ値の変化に応じて、2の値が「こんにちは、●○さん!」のように変化するわけです。

 データをページに反映するために一切のコードを記述する必要がない点、テキストボックスの値を何度変えても12の両者が同期される点を確認してください。

[Note]バインドを抑制するには?

 ちなみに、{{...}}をそのまま文字列として出力したい(=エクスプレッション式として認識させたくない)場合には、ng-non-bindable属性を利用します。

HTML
<div ng-non-bindable>{{"こんにちは、" + name + "さん!"}}</div>
エクスプレッション式をAngularJSで処理したくない場合
{{...}}の内容をそのまま表示
{{...}}の内容をそのまま表示

テキストボックスにデフォルト値を与える

 ng-model属性でモデルをひも付けた場合、<input>要素にvalue属性を付与してもテキストボックスにはデフォルト値は表示されません。ng-model属性によって、テキストボックスの値はモデルの値と同期しているからです。

 よって、テキストボックスにデフォルト値を与えるには、以下のようにコントローラーからスコープオブジェクトのプロパティを設定してやります。

HTML
<!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>
モデルのプロパティを設定するコード(bind2.html)
テキストボックスにデフォルト値が設定された
テキストボックスにデフォルト値が設定された
処理対象:データバインディング(Data Binding) カテゴリ:基本
処理対象:{{プロパティ名}} カテゴリ:式(Expressions)
API:ngModel(ng-model) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
API:ngNonBindable(ng-non-bindable) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)

※以下では、本稿の前後を合わせて5回分(第3回~第7回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

AngularJS TIPS
3. AngularJSでコントローラーを定義するには?

AngularJSアプリの最も基本的な構成要素である「コントローラー」の基礎として、コントローラー経由でスコープを準備し、テンプレートに反映させる方法を説明する。

AngularJS TIPS
4. AngularJSの依存性注入を利用するには?

AngularJSに標準搭載されているDIコンテナー機能を使って、依存性を注入するためのさまざまな方法を解説する。

AngularJS TIPS
5. 【現在、表示中】≫ モデルをテキストボックスなどのフォーム要素にバインドするには?(ng-model)

ビューの変更をモデルに反映させ、逆にモデルの変更をビューに反映させる、AngularJSの双方向データバインディングの基本を解説する。デフォルト値の設定方法も説明。

AngularJS TIPS
6. モデルをビューにバインドするには?(ng-bind/ng-cloak)

エクスプレッションが一瞬表示されてしまう不具合を解消して、AngularJSの双方向データバインディングを実現する方法を説明する。

AngularJS TIPS
7. ビューにHTML文書をバインドするには?(ng-bind-html)

文字列をデータバインドした際に、標準で実施されるサニタイズ処理について紹介。また、サニタイズせずにHTMLのままのビューに反映させる方法も説明する。

サイトからのお知らせ

Twitterでつぶやこう!