Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Knockout.js绑定可以同时应用于容器标记和子体吗?_Javascript_Html_Knockout.js - Fatal编程技术网

Javascript Knockout.js绑定可以同时应用于容器标记和子体吗?

Javascript Knockout.js绑定可以同时应用于容器标记和子体吗?,javascript,html,knockout.js,Javascript,Html,Knockout.js,让我用一个简单的例子来回答这个问题 我有一个HTML表,其中的行由observableArray控制。它工作得很好 但是,如果ObservalArray中有零个元素,我希望有一行这样说。我尝试了这种标记,哪种“类型”有效: 尚未指定联系人。 SNIP-当元素>零时,有行的tbody在这里 当我说“种类”时,我的意思是明显的。它确实出现在零元素上,并且确实消失在>零元素上,就像你所期望的那样。但是,当您打开DOM检查器(开发工具)并查看内存中的DOM时,您会发现有两个tbody部分,而不是一个

让我用一个简单的例子来回答这个问题

我有一个HTML表,其中的行由observableArray控制。它工作得很好

但是,如果ObservalArray中有零个元素,我希望有一行这样说。我尝试了这种标记,哪种“类型”有效:


尚未指定联系人。
SNIP-当元素>零时,有行的tbody在这里
当我说“种类”时,我的意思是明显的。它确实出现在零元素上,并且确实消失在>零元素上,就像你所期望的那样。但是,当您打开DOM检查器(开发工具)并查看内存中的DOM时,您会发现有两个tbody部分,而不是一个。现在一个tbody当然总是空的,但是两个tbody标记不是HTML5正确的,所以必须修正这不是期望的标记

作为一名优秀的新手,我尝试用虚拟元素解决这个问题:

<!-- ko if: $root.data.contacts().length == 0 -->
<tbody>
    <tr>
        <td>There are no contacts specified yet.</td>
    </tr>
</tbody>
<!-- /ko -->

尚未指定联系人。
不幸的是,这不适用于我们的构建过程:我们在压缩之前缩小HTML,注释被消除


我的印象是KO绑定应用于容器元素本身以及子元素,但事实似乎并非如此。有没有一种方法可以告诉KO将应用于容器元素和子元素,或者我需要以虚拟容器以外的其他方式更改标记?

与您一样,我的第一选择是用于
if
绑定的虚拟标记。但既然这不是一个选项,那么可交换模板呢

var-vm={
联系人:ko.observableArray()
};
ko.应用绑定(vm);
setTimeout(函数(){
联系人(['1','2','3']);
}, 2500);

尚未指定联系人。
将绑定应用于元素本身。它通过使用一个节点预处理器在运行时用虚拟(基于注释的)元素中的
repeat
绑定来包装元素来实现

var-vm={
联系人:ko.observableArray()
};
ko.应用绑定(vm);
setTimeout(函数(){
联系人(['1','2','3']);
}, 2500);

尚未指定联系人。

如果您的表中有两个
tbody
标签,您会面临什么问题?显然没有。我认为多个元素是非法的,但对规范的阅读表明允许多个元素。我的问题仍然是绑定到容器和子容器,但我关于HTML5正确性的假设是错误的。我会更新。
if
绑定控制包含的元素,而不是绑定所在的元素。如果您查看实时演示,您可以在文档页面上看到这一点。如果要使用
If
,可以有两个完整的表,每个表都包装在
If
绑定的div中。这将始终产生两个div,div是块级元素,可能会对标记产生负面影响,具体取决于用例。您在下面的答案中使用的新模板标记始终是干净的,没有孤立元素。事实上,您可以在标记中有一个可观察的字符串控件(可能很大)部分,这是设计中的一个范式转变!罗伊,我大吃一惊。真的很喜欢+1这个想法(我觉得模板很难,但是
swappable
templates是经典)。干杯mate@supercool我们通常不认为模板名是变量,但它可以是可观察的。我已经用组件做过几次了。一开始我不明白这一点,但8小时的睡眠对一切都有帮助!KO的模板文档中的相关内容是:“速记语法:如果只提供一个字符串值,KO会将其解释为要呈现的模板的ID。”这就清楚了为什么这个解决方案如此出色。荣誉@Roy-这真是太棒了。主要问题的答案是“不,KO只绑定到后代,没有办法不这样做”,以及“是的,有一种方法可以更改标记以产生所需的效果。”谢谢,回答得很好。这是一个非常有用的项目-谢谢发布它。事实上,我在问你的答案是否是我问题的更好答案。在过去的几天里,翻模板(目前是选定的答案)并不是100%的公园漫步。模板翻转的期望是一次只有一个模板在DOM中(删除旧的,添加新的),但我已经证明,实际上你不能指望这一点。由于订阅服务器的执行顺序无法控制,因此可能出现“添加新的,删除旧的”情况,这会对绑定造成严重破坏。将研究并可能改变答案。
<!-- ko if: $root.data.contacts().length == 0 -->
<tbody>
    <tr>
        <td>There are no contacts specified yet.</td>
    </tr>
</tbody>
<!-- /ko -->