如何在数据绑定视图中模板化If Else结构

How to template If-Else structures in data-bound views?

本文关键字:If Else 结构 数据绑定 视图      更新时间:2023-11-12

我经常发现自己在基于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>

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

  • 和你现在的if/ifnot组合。这很好用,也不太冗长。

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

  • 另一种选择是使用动态模板。您可以将一个区域绑定到一个或多个模板,模板名称是基于可观察到的。这是我不久前就这个话题写的一篇帖子: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)作为第一个参数,并返回要使用的模板的名称。

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

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

当使用if:/ifnot:的组合时,为了避免重新计算敲除绑定,您可以将它们与"with:"构造结合使用

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

现在还有knockout-else绑定/插件(我编写它是为了解决这个问题)。