【问题标题】:Knockout JS - Containerless Control Breaks Foreach using TemplateKnockout JS - 无容器控制使用模板打破 Foreach
【发布时间】:2013-12-05 19:44:04
【问题描述】:

为冗长的标题道歉。希望一些代码能让事情更清楚。

在开始之前,我使用的是 KnockoutJs 版本 3.0.0、bootstrap 3 和 jquery 1。 7.1。此问题与 KnockoutJS 有关。

我有以下 html,它根据我的底层 javascript 模型创建一个表单。

        <form role="form" data-bind="foreach: { data: controls, as: 'control' }" >
        <div class="form-group control-form-group" data-bind="attr:{class: $root.cssControlClassColumnWidth }, visible: control.isVisible">
            <fieldset class="control-border" data-bind="
                event:{
                    dragstart: function(control, event) { $root.dragStartControl($parent,control, event) },
                    dragover: function(control, event) { $root.dragOverControl(event) }
                    }">
                <legend class="control-border">
                    <b data-bind="text: control.name"></b>
                    <span class="glyphicon glyphicon-remove-circle btn-control-remove text-danger" data-bind="visible: $root.inCustomisationMode,click: $root.removeControl"></span>
                </legend>
                <div class="form-inline" data-bind="foreach: {data: parameters, as: 'parameter'}">
                    <div class="form-group" >
                        <div data-bind="template: { name: parameter.template, data: parameter }"></div>
                    </div>
                </div>
            </fieldset>
        </div>
    </form>

这很好用。但是当我将代码更改为以下代码(添加无容器控件)时,我的内部 foreach 循环使用了由 parameter.template 值确定的模板。

        <form role="form" data-bind="foreach: { data: controls, as: 'control' }" >
        <!-- ko if:true -->         
        <div class="row">    
        <!-- /ko -->    
            <div class="form-group control-form-group" data-bind="attr:{class: $root.cssControlClassColumnWidth }, visible: control.isVisible">
                <fieldset class="control-border" data-bind="
                  event:{
                      dragstart: function(control, event) { $root.dragStartControl($parent,control, event) },
                      dragover: function(control, event) { $root.dragOverControl(event) }
                      }">
                    <legend class="control-border">
                        <b data-bind="text: control.name"></b>
                        <span class="glyphicon glyphicon-remove-circle btn-control-remove text-danger" data-bind="visible: $root.inCustomisationMode,click: $root.removeControl"></span>
                    </legend>
                    <div class="form-inline" data-bind="foreach: {data: parameters, as: 'parameter'}">
                        <div class="form-group" >
                            <div data-bind="template: { name: parameter.template, data: parameter }"></div>
                        </div>
                    </div>
                </fieldset>
            </div>
        <!-- ko if:true -->         
        </div>    
        <!-- /ko --> 
    </form>

如您所见,我要做的就是添加一行(我将添加一个变量,该变量将控制我在此工作后每行添加的表单组的数量)。这应该是微不足道的,但我的内部 foreach 似乎无法使用该模板(请参阅下面的示例模板)。

    <script type="text/html" id="parameterComboBoxTemplate">
    <label data-bind="text: name"></label>
    <select class="input-sm" data-bind="options: values, value: selectedValue"></select>
</script>

希望有人能解释一下为什么我会看到这种奇怪的行为。

如果我可以添加任何其他内容来帮助确定问题,请告诉我。

【问题讨论】:

    标签: javascript jquery twitter-bootstrap knockout.js


    【解决方案1】:

    Knockout 的“无容器控制流语法”使用 cmets 作为“虚拟元素”。他们仍然必须遵循元素规则。这意味着开始和结束标签之间的 HTML 必须是完整的元素。所以这就是层次结构的表现:

    <form role="form" data-bind="foreach: { data: controls, as: 'control' }" >
        <!-- ko if:true -->         
            <div class="row">    
                <!-- /ko -->             <--- ignored
                <div class="form-group control-form-group" data-bind="attr:{class: $root.cssControlClassColumnWidth }, visible: control.isVisible">
                    ...
                </div>
                <!-- ko if:true -->      <--- will generate an error
            </div>    
        <!-- /ko --> 
    </form>
    

    【讨论】:

    • 谢谢迈克尔,现在说得通了。你知道 Knockout 可以通过什么方式提供我需要的功能吗?
    【解决方案2】:

    如果有人对我如何解决我的问题感兴趣,这里是我的代码:

        <form role="form" data-bind="foreach: { data: controls, as: 'control' }" >
            <!-- We only want to create a row of controls on every even number (We may want to change this
                to have a different number of controls in the row so changing the method name to something 
                more generic would be better -->
            <!-- ko if: $root.isRowEven($index()) -->
    
                <!-- HERE WE WANT TO ADD TWO CONTROLS TO THE ROW!!-->
                <!-- ko if: $parent.controls[$index() + 1] -->
                <div class="row">
                    <div class="form-group control-form-group" data-bind="attr:{class: $root.cssControlClassColumnWidth }, visible: control.isVisible">
                        <fieldset class="control-border" data-bind="
                            event:{
                                dragstart: function(control, event) { $root.dragStartControl($parent,control, event) },
                                dragover: function(control, event) { $root.dragOverControl(event) }
                                }">
                            <legend class="control-border"> 
    
                                <b data-bind="text: control.name"></b>
                                <span class="glyphicon glyphicon-remove-circle btn-control-remove text-danger" data-bind="visible: $root.inCustomisationMode,click: $root.removeControl"></span>
                            </legend>
                            <div class="form-inline" data-bind="foreach: {data: parameters, as: 'parameter'}">
                                <div class="form-group" >
                                    <div data-bind="template: { name: parameter.template, data: parameter }"></div>
                                </div>
                            </div>
                        </fieldset>
                    </div>
                    <div class="form-group control-form-group" data-bind="attr:{class: $root.cssControlClassColumnWidth }, visible: control.isVisible">
                        <fieldset class="control-border" data-bind="
                            event:{
                                dragstart: function(control, event) { $root.dragStartControl($parent,control, event) },
                                dragover: function(control, event) { $root.dragOverControl(event) }
                                }">
                            <legend class="control-border">                   
                                <b data-bind="text: $parent.controls[$index() + 1].name"></b>
                                <span class="glyphicon glyphicon-remove-circle btn-control-remove text-danger" data-bind="visible: $root.inCustomisationMode,click: $root.removeControl"></span>
                            </legend>
                            <div class="form-inline" data-bind="foreach: {data: $parent.controls[$index() + 1].parameters, as: 'parameter'}">
                                <div class="form-group" >
                                    <div data-bind="template: { name: parameter.template, data: parameter }"></div>
                                </div>
                            </div>
                        </fieldset>
                    </div>
                </div>
                <!-- /ko --> 
    
    
                <!-- HERE WE WANT TO ADD ONE CONTROL TO THE ROW!!-->
                <!-- ko if: !$parent.controls[$index() + 1] -->
                <div class="row">
                    <div class="form-group control-form-group" data-bind="attr:{class: $root.cssControlClassColumnWidth }, visible: control.isVisible">
                        <fieldset class="control-border" data-bind="
                            event:{
                                dragstart: function(control, event) { $root.dragStartControl($parent,control, event) },
                                dragover: function(control, event) { $root.dragOverControl(event) }
                                }">
                            <legend class="control-border"> 
                                <b data-bind="text: control.name"></b>
                                <span class="glyphicon glyphicon-remove-circle btn-control-remove text-danger" data-bind="visible: $root.inCustomisationMode,click: $root.removeControl"></span>
                            </legend>
                            <div class="form-inline" data-bind="foreach: {data: parameters, as: 'parameter'}">
                                <div class="form-group" >
                                    <div data-bind="template: { name: parameter.template, data: parameter }"></div>
                                </div>
                            </div>
                        </fieldset>
                    </div>
                </div>
                <!-- /ko --> 
    
            <!-- /ko -->  
    
    
    
    
        </form>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-13
      • 2014-02-28
      • 2014-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      相关资源
      最近更新 更多