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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11553999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:17:48  来源:igfitidea点击:

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

javascriptknockout.js

提问by Jensen Ching

I constantly find myself using this idiom in KO-based HTML templates:

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

Is there a better/cleaner way to do conditionals in KO, or is there a better approachthan just using traditional if-else constructs?

在 KO 中是否有更好/更简洁的方法来执行条件,或者是否有比仅使用传统的 if-else 结构更好的方法

Also, I would just like to point out that some versions of Internet Explorer (IE 8/9) don't parse the above example correctly. Please see this SO questionfor more information. The quick summary is, don't use comments (virtual bindings) inside table tags to support IE. Use the tbodyinstead:

另外,我想指出某些版本的 Internet Explorer (IE 8/9) 不能正确解析上面的示例。请参阅此 SO 问题以获取更多信息。快速总结是,不要在表标签内使用注释(虚拟绑定)来支持 IE。使用tbody来代替:

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

采纳答案by RP Niemeyer

There are a couple different ways that you can handle this type of code.

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

  • with an if/ifnot combination like you are now. This works fine and is not terribly verbose.

  • Michael Best's switch/case binding (https://github.com/mbest/knockout-switch-case) is quite flexible and can let you easily handle this and more complicated ones (more states than true/false).

  • Another option is to use dynamic templates. You would bind an area to one or more templates with the template name being used based on an observable. Here is a post that I wrote on this topic a while back: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html. In your scenario, it might look like:

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

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

  • 另一种选择是使用动态模板。您可以将一个区域绑定到一个或多个模板,其中使用的模板名称基于一个 observable。这是我不久前写的关于这个主题的帖子:http: //www.knockmeout.net/2011/03/quick-tip-dynamically-changed.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>

The getCellTemplatefunction could live wherever, but would be given the item ($data) as the first argument and would return the name of the template to use.

getCellTemplate函数可以存在于任何地方,但会被赋予项 ($data) 作为第一个参数,并返回要使用的模板的名称。

回答by Michael Best

One approach is to use named templates (which can support passing arguments):

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

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

Another option is use my switch/case plugin, which would work like this:

另一种选择是使用我的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 -->

回答by Dmitry Komin

To avoid recalculation of knockout binding when using combination of if: / ifnot: you can use them in conjunction with 'with:' construction

为避免在使用 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 Brian M. Hunt

There is now also the knockout-elsebinding/plugin (that I wrote to address this issue).

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