让我用一个简单的案例来设置问题。
我有一个HTML表,其行由observableArray控制。它很棒。
如果observableArray中有零元素,我想要一行来说明。我试过这个标记,“有点”有效:
<tbody data-bind="if: $root.data.contacts().length == 0">
<tr>
<td>There are no contacts specified yet.</td>
</tr>
</tbody>
<tbody data-bind="foreach: $root.data.contacts">
SNIP - a tbody with the rows is here when elements > zero
</tbody>
当我说“有点”时,我的意思是可见的。它确实出现在零元素上并且确实在&gt;处消失了。零元素就像你期望的那样。但是,当您打开DOM检查器(开发工具)并查看内存中的DOM时,您会发现有两个 tbody 部分,而不是一个部分。现在一个 tbody 总是空的,但是两个 tbody 标签不是HTML5正确的,所以必须修复这不是所需的标记
作为Knockout新手,我尝试用虚拟元素解决这个问题:
<!-- ko if: $root.data.contacts().length == 0 -->
<tbody>
<tr>
<td>There are no contacts specified yet.</td>
</tr>
</tbody>
<!-- /ko -->
不幸的是,这对我们的构建过程不起作用:我们在压缩之前缩小HTML并消除注释。
我的印象是KO绑定适用于CONTAINER ELEMENT ITSELF以及后代,但似乎并非如此。有没有办法告诉KO应用于容器元素以及子元素,还是我需要以某种方式更改标记而不是虚拟容器?
答案 0 :(得分:2)
和你一样,我的第一选择是if
绑定的虚拟标签。但由于这不是一个选项,可交换模板怎么样?
var vm = {
contacts: ko.observableArray()
};
ko.applyBindings(vm);
setTimeout(function() {
vm.contacts(['One', 'Two', 'Three']);
}, 2500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<template id="empty-body">
<tbody>
<tr>
<td>There are no contacts specified yet.</td>
</tr>
</tbody>
</template>
<template id="normal-body">
<tbody data-bind="foreach: contacts">
<tr>
<td data-bind="text:$data"></td>
</tr>
</tbody>
</template>
<table data-bind="template: contacts().length === 0 ? 'empty-body' : 'normal-body'"></table>
答案 1 :(得分:0)
Knockout-Repeat binding将绑定应用于元素本身。它通过使用节点预处理器在运行时用虚拟(基于注释)元素中的repeat
绑定包装元素来实现。
var vm = {
contacts: ko.observableArray()
};
ko.applyBindings(vm);
setTimeout(function() {
vm.contacts(['One', 'Two', 'Three']);
}, 2500);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="https://rawgit.com/mbest/knockout-repeat/master/knockout-repeat.js"></script>
<table>
<tbody data-bind="repeat: !contacts().length && 1">
<tr>
<td>There are no contacts specified yet.</td>
</tr>
</tbody>
<tbody data-bind="repeat: contacts().length && 1" data-repeat-bind="foreach: contacts">
<tr>
<td data-bind="text:$data"></td>
</tr>
</tbody>
</table>
&#13;