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

AngularJS TIPS

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

2015年3月19日

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

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

 別稿「TIPS:モデルをテキストボックスなどのフォーム要素にバインドするには?」でも触れたように、AngularJSでは双方向データバインディングを利用することで、ごくシンプルなコードでモデル/ビュー間の値を同期できます。

 以下に、別稿のサンプルを再掲しておきます。これで、テキストボックスへの入力値に基づいて、「こんにちは、●○さん!」のようなメッセージが表示されます*1

  • *1 詳しい解説は別稿を参照してください。
HTML
<!DOCTYPE html>
<html ng-app>
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body>
<form>
  <label for="name">名前:</label>
  <!--テキストボックスnameに対して、nameプロパティをひも付け-->
  <input id="name" name="name" type="text" ng-model="name" />
  <!--nameプロパティを基にあいさつメッセージを生成-->
  <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)
テキストボックスの値に応じて、あいさつメッセージを表示

 もっとも、この方法にはいささかの問題があります。というのも、ページを起動した最初のタイミングで、{{...}}というエクスプレッション(=式)が(大概は一瞬だけですが)表示されてしまうのです。AngularJSが初期化処理を終えて、エクスプレッションを処理するまでのタイムラグによって生じる不具合です。

 生のテンプレートがエンドユーザーに露出してしまうのは、一瞬とはいえ、望ましいことではありません。そこで利用するのがng-bind属性です。

ng-bind属性によるデータバインディング

 ng-bind属性は、モデルをビューに明示的にバインドするためのディレクティブで、例えば上のサンプルの太字部分はng-bind属性を利用することで、以下のように書き換えることができます。属性値全体をダブルクォート"でくくっていますので、文字列リテラルはシングルクォート'でくくっている点に注意してください。

HTML
<div ng-bind="'こんにちは、' + name + 'さん!'"></div>
ng-bind属性で書き換えた例

 エクスプレッションに比べると、冗長に見えますが、一点利点があります。というのも、ng-bindそのものは属性なので、{{...}}のように最初にページに表示されてしまう不具合を解消できます。

ng-cloak属性による表示の制御

 エクスプレッションを用いる場合でも、ng-cloak属性を利用することで、処理前の{{...}}が表示されてしまうのを防ぐことができます。以下は、先ほどのコードをng-cloak属性で書き換えた例です。

HTML
<div ng-cloak>{{"こんにちは、" + name + "さん!"}}</div>
ng-cloak属性で書き換えた例

 ng-cloak属性は、AngularJS内部で生成される以下のスタイルシートに従って、該当する要素を非表示にします。

CSS
[ng:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}
AngularJSで内部的に生成されるスタイルシート

 AngularJSは、ng-cloak属性を見つけると、属性を破棄し、要素を表示状態にします。ただし、「スタイルシートを適用する」という性質上、ng-cloak属性を利用する場合には、AngularJSをページの先頭でインポートしなければならない点に注意してください(つまり、上記のコードでは</body>タグの直前に記載した<script>タグを、<head>要素の中に記載する必要がある)。さもないと、{{...}}が一瞬だけ表示されてしまいます。

 なお、ng-cloak属性は<body>要素(=ページ全体)に適用することもできますが、あまり望ましい方法ではありません。というのも、ページ全体が非表示になってしまうので、それだけレンダリングのタイミングが遅れるからです。ng-cloak属性は、まず{{...}}を利用している要素個別に付与することをお勧めします。

処理対象:データバインディング(Data Binding) カテゴリ:基本
処理対象:{{プロパティ名}} カテゴリ:式(Expressions)
API:ngBind(ng-bind) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
API:ngCloak(ng-cloak) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)

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

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のままのビューに反映させる方法も説明する。

AngularJS TIPS
8. イベントリスナーを登録するには?(ng-clickなど)

AngularJSで、ディレクティブを使ってイベントリスナーを設定する方法を解説。また、イベントリスナーにイベントオブジェクトを渡して参照する方法も説明する。

サイトからのお知らせ

Twitterでつぶやこう!