"if" バインディング
用途
if
バインディングは、与えられた値および式の評価結果が true
(もしくは true
に相当する値: null
でないオブジェクトもしくは空でない文字列等)
のときに、マークアップの一部を表示させます。
if
バインディングは、一見 visible
バインディング
と同様の役割を演じます。異なるのは、visible
バインディングでは対象のマークアップは常に
DOM 上に存在しており、CSS を制御することで非表示にしている点です。
常に DOM 上に存在しているため、配下エレメントの data-bind
も常に適用された状態です。
if
バインディングでは、対象のマークアップを物理的に追加・削除します。
したがって、配下エレメントの data-bind
は if
にバインドされた評価値が
true
のときにのみ適用されます。
例1
Observable の値に従って、マークアップの一部が動的に追加・削除される様子を示します。
ソースコード: View
<label><input type="checkbox" data-bind="checked: displayMessage" /> メッセージを表示</label> <div data-bind="if: displayMessage">メッセージですぞ!</div>
ソースコード: ViewModel
ko.applyBindings({ displayMessage: ko.observable(false) });
例2
次の例では、"水星"の <div>
の内容は空になりますが、
"地球"の場合内容が含まれます。理由は、地球には null
でない capital
プロパティがあるからです。反して水星のプロパティは null
です。
<ul data-bind="foreach: planets"> <li> 惑星: <b data-bind="text: name"> </b> <div data-bind="if: capital"> 都市: <b data-bind="text: capital.cityName"> </b> </div> </li> </ul> <script> ko.applyBindings({ planets: [ { name: '水星', capital: null }, { name: '地球', capital: { cityName: '東京' } } ] }); </script>
このコードを正しく動作させるために、if
バインディングが不可欠である重要な理由があります。
if
バインディングなしで (代わりにvisible
バインディングを使った場合など)
は、"水星"の capital.cityName
を評価しようとしたとき、capital
自体が
null
であるためエラーになってしまいます。
JavaScript では、null
や undefined
である値のサブプロパティを参照することは許されません。
パラメタ
-
主パラメタ
判定に使用される式です。
true
(もしくは相当する値) と評価された場合、 内包するマークアップはドキュメント上に展開され、そのマークアップに含まれるdata-bind
属性が適切に処理されます。false
と評価された場合、内包するマークアップはドキュメントから削除されます。式が Observable を伴う場合、その値が変更されるたびに式が再評価されます。 その際、
if
ブロックに含まれるマークアップも値が変更される度に追加・削除されます。data-bind
属性は、マークアップの新たなコピーが追加される度に処理されます。 -
追加パラメタ
なし
(注) コンテナエレメントなしで "if" を使う
ときには、if
バインディングを適用するためのコンテナエレメントを設置することなく、
マークアップの一部の あり/なし をコントロールしたいことがあるかもしれません。
例えば、次の例のように <li>
エレメントをコントロールしたい場合...
<ul> <li>このアイテムは常に表示させたい</li> <li>このアイテムの あり/なし を動的に切り替えたい</li> </ul>
この場合、<ul>
タグに if
を配置することはできません。
(最初の<li>
タグにまで影響してしまいます。)
さらに、2つ目の <li>
タグを別のタグで囲むことも不可能です。
(<ul>
タグの直下に <li>
以外のコンテナエレメントを挿入することはできません。)
対処法は、コメントタグを用いた コンテナレス構文 を使うことです。
<ul> <li>このアイテムは常に表示させたい</li> <!-- ko if: someExpressionGoesHere --> <li>このアイテムの あり/なし を動的に切り替えたい</li> <!-- /ko --> </ul>
このコメント <!--ko-->
と <!--/ko-->
は、
内部にマークアップを含む“バーチャルエレメント”の 開始 / 終了 のマーカーとしての役割をもっています。
Knockout はこのバーチャルエレメント構文を理解し、本当のコンテナエレメントがあるかのようにバインドします。
依存
Knockout コアライブラリ以外、なし。