如何在数据绑定视图中模板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 --> 

是否有一个更好的/更清洁的方式来做关系条件,还是有一个更好的方法比只使用传统的if-else结构?

另外,我只想指出某些版本的Internet Explorer(IE 8/9)不能正确parsing上述示例。 请参阅此SO问题的更多信息。 简要总结一下,不要在表标签内部使用注释(虚拟绑定)来支持IE。 使用tbody代替:

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

有几种不同的方式可以处理这种types的代码。

  • 与你现在是否像if / ifnot组合一样。 这工作正常,不是非常详细。

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

  • 另一个select是使用dynamic模板。 您可以将一个区域绑定到一个或多个模板,并使用基于observable的模板名称。 这是我后来在这个话题上写的一篇文章: 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> 

另一个select是使用我的开关/案例插件 ,这将是这样的工作:

 <!-- 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的组合时避免重新计算knockout绑定,可以将它们与'with:'结合使用

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

现在还有knockout-else binding / plugin(我写的是为了解决这个问题)。