如何在数据绑定视图中对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
Brian M. Hunt

Answers:


64

您可以通过几种不同的方式来处理这种类型的代码。

  • 和现在一样使用if / ifnot组合。这很好用,并且不是很冗长。

  • Michael Best的switch / case绑定(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)作为第一个参数,并将返回要使用的模板的名称。


奇怪,我的HTML无法显示。也只是注意到迈克尔给出了几乎相同的答案。
RP Niemeyer

感谢您提供完整的选项列表。我想我的原始代码样式适用于简单情况。如有需要,我将检查其他选项。
Jensen Ching

有没有一种方法可以进一步自定义模板,例如“ template:data,proppertyName:'email'”和模板中的data-bind =“ text:$ data [propertyName]”。
Onur Topal '04

@OnurTOPAL-是的,只要您有一个变量propertyName,就可以动态确定模板名称。
RP Niemeyer 2014年

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

谢谢。在需要时,我会牢记switch / case插件。
Jensen Ching

2
不错的插件,您到了那里!肯定会使用这个。
库克斯2014年

命名模板效果很好,并且它支持通过嵌套三元运算符来键入场景。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.