AngularJS TIPS
モデルをビューにバインドするには?(ng-bind/ng-cloak)
エクスプレッションが一瞬表示されてしまう不具合を解消して、AngularJSの双方向データバインディングを実現する方法を説明する。
別稿「TIPS:モデルをテキストボックスなどのフォーム要素にバインドするには?」でも触れたように、AngularJSでは双方向データバインディングを利用することで、ごくシンプルなコードでモデル/ビュー間の値を同期できます。
以下に、別稿のサンプルを再掲しておきます。これで、テキストボックスへの入力値に基づいて、「こんにちは、●○さん!」のようなメッセージが表示されます*1。
- *1 詳しい解説は別稿を参照してください。
<!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>
|
もっとも、この方法にはいささかの問題があります。というのも、ページを起動した最初のタイミングで、{{...}}
というエクスプレッション(=式)が(大概は一瞬だけですが)表示されてしまうのです。AngularJSが初期化処理を終えて、エクスプレッションを処理するまでのタイムラグによって生じる不具合です。
生のテンプレートがエンドユーザーに露出してしまうのは、一瞬とはいえ、望ましいことではありません。そこで利用するのがng-bind
属性です。
ng-bind属性によるデータバインディング
ng-bind
属性は、モデルをビューに明示的にバインドするためのディレクティブで、例えば上のサンプルの太字部分はng-bind
属性を利用することで、以下のように書き換えることができます。属性値全体をダブルクォート"
でくくっていますので、文字列リテラルはシングルクォート'
でくくっている点に注意してください。
<div ng-bind="'こんにちは、' + name + 'さん!'"></div>
|
エクスプレッションに比べると、冗長に見えますが、一点利点があります。というのも、ng-bind
そのものは属性なので、{{...}}
のように最初にページに表示されてしまう不具合を解消できます。
ng-cloak属性による表示の制御
エクスプレッションを用いる場合でも、ng-cloak
属性を利用することで、処理前の{{...}}
が表示されてしまうのを防ぐことができます。以下は、先ほどのコードをng-cloak
属性で書き換えた例です。
<div ng-cloak>{{"こんにちは、" + name + "さん!"}}</div>
|
ng-cloak
属性は、AngularJS内部で生成される以下のスタイルシートに従って、該当する要素を非表示にします。
[ng:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}
|
AngularJSは、ng-cloak
属性を見つけると、属性を破棄し、要素を表示状態にします。ただし、「スタイルシートを適用する」という性質上、ng-cloak
属性を利用する場合には、AngularJSをページの先頭でインポートしなければならない点に注意してください(つまり、上記のコードでは</body>
タグの直前に記載した<script>
タグを、<head>
要素の中に記載する必要がある)。さもないと、{{...}}
が一瞬だけ表示されてしまいます。
なお、ng-cloak
属性は<body>
要素(=ページ全体)に適用することもできますが、あまり望ましい方法ではありません。というのも、ページ全体が非表示になってしまうので、それだけレンダリングのタイミングが遅れるからです。ng-cloak
属性は、まず{{...}}
を利用している要素個別に付与することをお勧めします。
処理対象:{{プロパティ名}} カテゴリ:式(Expressions)
API:ngBind(ng-bind) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
API:ngCloak(ng-cloak) カテゴリ:ng(コアモジュール) > directive(ディレクティブ)
※以下では、本稿の前後を合わせて5回分(第4回~第8回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
5. モデルをテキストボックスなどのフォーム要素にバインドするには?(ng-model)
ビューの変更をモデルに反映させ、逆にモデルの変更をビューに反映させる、AngularJSの双方向データバインディングの基本を解説する。デフォルト値の設定方法も説明。
6. 【現在、表示中】≫ モデルをビューにバインドするには?(ng-bind/ng-cloak)
エクスプレッションが一瞬表示されてしまう不具合を解消して、AngularJSの双方向データバインディングを実現する方法を説明する。
7. ビューにHTML文書をバインドするには?(ng-bind-html)
文字列をデータバインドした際に、標準で実施されるサニタイズ処理について紹介。また、サニタイズせずにHTMLのままのビューに反映させる方法も説明する。
8. イベントリスナーを登録するには?(ng-clickなど)
AngularJSで、ディレクティブを使ってイベントリスナーを設定する方法を解説。また、イベントリスナーにイベントオブジェクトを渡して参照する方法も説明する。