データバインドビューでIf-Else構造をテンプレート化する方法


95

私は常にこのイディオムをKOベースのHTMLテンプレートで使用していることに気づきました。

<!-- ko if: isEdit -->
<td><input type="text" name="email" data-bind="value: email" /></td>
<!-- /ko -->
<!-- ko ifnot: isEdit -->
<td data-bind="text: email"></td>
<!-- /ko -->

KOで条件付きを行うためのより良い/よりきれいな方法はありますか、またはより良いアプローチがありますか従来のif-else構文を使用よりもますか?

また、一部のバージョンのInternet Explorer(IE 8/9)が上記の例を正しく解析しないことも指摘しておきます。詳細については、このSOの質問を参照してください。簡単にまとめると、IEをサポートするためにテーブルタグ内でコメント(仮想バインディング)を使用しないでください。tbody代わりに使用してください:

<tbody data-bind="if: display"><tr><td>hello</td></tr></tbody>

これを見ている誰もが追跡したいと思うかもしれgithub.com/knockout/knockout/issues/962
ブライアン・M・ハント

回答:


64

このタイプのコードを処理する方法はいくつかあります。

  • あなたのようなif / ifnotの組み合わせで。これは正常に機能し、ひどく冗長ではありません。

  • Michael Bestのスイッチ/ケースバインディング(https://github.com/mbest/knockout-switch-case)は非常に柔軟で、これとより複雑なもの(true / falseより多くの状態)を簡単に処理できます。

  • 別のオプションは、動的テンプレートを使用することです。オブザーバブルに基づいてテンプレート名が使用されている1つ以上のテンプレートに領域をバインドします。これは、しばらく前にこのトピックについて書いた投稿です:http : //www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html。シナリオでは、次のようになります。

<td data-bind="template: $root.getCellTemplate"></td>

<script id="cellEditTmpl" type="text/html">
    <input type="text" name="email" data-bind="value: email" />
</script>

<script id="cellTmpl" type="text/html">
    <span data-bind="text: email"></span>
</script>

getCellTemplate機能はどこに住んでいる可能性がありますが、最初の引数として項目($データ)与えられることになると、使用するテンプレートの名前を返します。


奇妙なことに、HTMLが表示されません。また、マイケルがほぼ同じ答えを出したことにも気づきました。
RPニーマイヤー2012

オプションの包括的なリストをありがとう。元のコードスタイルは単純なケースで機能すると思います。必要に応じて、他のオプションを確認します。
Jensen Ching

"template:data、proppertyName: 'email'"やテンプレートdata-bind = "text:$ data [propertyName]"など、テンプレートをさらにカスタマイズする方法はありますか。
Onur Topal 2014

@OnurTOPAL-はい、変数propertyNameがあれば、テンプレート名を動的に決定できます。
RPニーマイヤー2014

44

1つの方法は、名前付きテンプレートを使用することです(引数の受け渡しをサポートできます)。

<!-- ko template: isEdit() ? 'emailEdit' : 'emailDisplay' --><!-- /ko -->
<script id="emailEdit" type="text/html">
    <td><input type="text" name="email" data-bind="value: email" /></td>
</script>
<script id="emailDisplay" type="text/html">
    <td data-bind="text: email"></td>
</script>

別のオプションは、次のように機能する私のスイッチ/ケースプラグインを使用することです:

<!-- ko switch -->
    <!-- ko case: isEdit -->
        <td><input type="text" name="email" data-bind="value: email" /></td>
    <!-- /ko -->
    <!-- ko case: $else -->
        <td data-bind="text: email"></td>
    <!-- /ko -->
<!-- /ko -->

ありがとう。必要に応じて、switch / caseプラグインを念頭に置いておきます。
Jensen Ching

2
あなたがそこに着いた素敵なプラグイン!確かにこれを使います。
Kukks 2014年

名前付きテンプレートはうまく機能し、3項演算子をネストすることにより、if elseif elseif elseタイプのシナリオをサポートします。

4

if:/ ifnot:の組み合わせを使用するときにノックアウトバインディングの再計算を回避するには、「with:」構造と組み合わせて使用​​できます。

    <!-- ko with: $data.DoSomePerformanceCriticalWork($data.SomeParameter()) -->
        <!-- ko if: $data.Condition() -->
           ... some markup ...
        <!-- /ko -->
        <!-- ko ifnot: $data.Condition() -->
           ... some markup ...
        <!-- /ko -->
    <!-- /ko -->

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.