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>
4

4 回答 4

64

有几种不同的方法可以处理这种类型的代码。

  • 像现在这样使用 if/ifnot 组合。这工作正常并且不是非常冗长。

  • Michael Best 的 switch/case 绑定 ( https://github.com/mbest/knockout-switch-case ) 非常灵活,可以让您轻松处理这个和更复杂的那些(比 true/false 更多的状态)。

  • 另一种选择是使用动态模板。您可以将一个区域绑定到一个或多个模板,并使用基于 observable 的模板名称。这是我不久前就这个主题写的一篇文章:http ://www.knockmeout.net/2011/03/quick-tip-dynamically-chang.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) 作为第一个参数,并返回要使用的模板的名称。

于 2012-07-19T05:09:22.663 回答
44

一种方法是使用命名模板(可以支持传递参数):

<!-- 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>

另一种选择是使用我的switch/case 插件,它的工作方式如下:

<!-- 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 -->
于 2012-07-19T05:07:18.477 回答
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 -->
于 2014-08-12T14:36:15.620 回答
2

现在还有knockout-else绑定/插件(我写来解决这个问题)。

于 2014-10-13T04:18:28.063 回答