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

后端 未结 4 962
陌清茗
陌清茗 2020-12-12 20:01

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




        
相关标签:
4条回答
  • 2020-12-12 20:31

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

        <!-- ko with: $data.DoSomePerformanceCriticalWork($data.SomeParameter()) -->
            <!-- ko if: $data.Condition() -->
               ... some markup ...
            <!-- /ko -->
            <!-- ko ifnot: $data.Condition() -->
               ... some markup ...
            <!-- /ko -->
        <!-- /ko -->
    
    0 讨论(0)
  • 2020-12-12 20:32

    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:

    <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 getCellTemplate function could live wherever, but would be given the item ($data) as the first argument and would return the name of the template to use.

    0 讨论(0)
  • 2020-12-12 20:44

    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:

    <!-- 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 -->
    
    0 讨论(0)
  • 2020-12-12 20:55

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

    0 讨论(0)
提交回复
热议问题