长篇大论的道歉。希望一些代码能让事情变得更加清晰。
在开始之前,我使用的是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>
这很好用。但是当我将代码更改为以下内容(添加无容器控件)时,不会显示使用由parameter.template值确定的模板的内部foreach循环。
<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>
希望有人可以解释为什么我会看到这种奇怪的行为。
如果我还有其他任何内容可以帮助您确定问题,请告诉我。
答案 0 :(得分:3)
Knockout的“无容器控制流语法”使用注释作为“虚拟元素”。他们仍然必须遵守元素规则。这意味着开始和结束标记之间的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>
答案 1 :(得分:1)
如果有人对我如何解决我的问题感兴趣,请参阅我的代码:
<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>