web-dev-qa-db-ja.com

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

私は、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)の一部のバージョンは上記の例を正しく解析しないことを指摘したいと思います。詳細については this SO question をご覧ください。簡単に要約すると、IEをサポートするためにテーブルタグ内でコメント(仮想バインディング)を使用しないでください。代わりにtbodyを使用してください。

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

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

  • あなたのような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関数はどこにでも存在できますが、最初の引数としてアイテム($ data)が与えられ、使用するテンプレートの名前を返します。

62
RP Niemeyer

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>

別のオプションは、my switch/case plugin を使用することです。これは次のように機能します。

<!-- 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 -->
43
Michael Best

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

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

knockout-else binding/pluginもあります(この問題に対処するために書いたものです)。

1
Brian M. Hunt