Knockoutjs 在尝试创建一系列无序列表时抛出异常

Knockoutjs throws exception when trying to create series of unordered lists

本文关键字:无序 列表 抛出异常 一系列 创建 Knockoutjs      更新时间:2023-09-26

我正在尝试使用foreach:上下文创建一系列<ul>标签。 目标是遍历列表,并为每个第 4 个项目启动一个新<ul>。 到目前为止,我的代码是:

<ul data-bind="foreach: Areas">
   <li><span>
      <input type="checkbox" data-bind="value: AreaId, checked: $root.AreasImpacted" />
      <label><span data-bind="text: Name"></span></label>
   </span></li>
   <!-- ko if: ($index() % 4 == 0) -->
   </ul><ul>
   <!-- /ko -->
</ul>

当我这样做时,我得到异常:

Microsoft JScript 运行时错误:找不到结束注释标记 匹配: KO 如果: ($index(( % 4 == 0(

它似乎不喜欢if注释块中的</li><li>内容,可能是因为 DOM 解析器正在为如何实际解析它而挠头。 如果我将其更改为:

<!-- ko if: ($index() % 4 == 0) -->
<li>Fake!</li>
<!-- /ko -->

然后它将完美运行(即,每 4 个元素创建一个假<li>

我也对实现这一目标的其他想法持开放态度。 谢谢!

是的,最初的DOM(在Knockout激活之前(是非法的,并且Knockout不能通过将HTML粘贴到DOM中来工作,它实际上将其复制到javascript DOM对象中,然后将其插入到DOM中。 </ul><ul>不是法律对象,因此 Knockout 无法将其转换为模板。即使可以,foreach绑定也在原始<ul>上,而不是由if启动的新绑定,因此添加项的 Knockout 代码仍将在第一个列表中运行。

因此,总而言之

,Knockout 的foreachtemplate绑定不能通过将 HTML 构建为字符串来工作。

您将需要一个更复杂的解决方案。

这样的东西会起作用,但我不知道这是否仍然是你想要的:

<!-- ko foreach: { data: chunkedList, as: 'areas' } -->
<span>SPLIT!</span>
<ul data-bind="foreach: areas">
    <li><span data-bind="text: name"></span></li>
</ul>
<!-- /ko -->
var Viewmodel = function(data) {
    var self = this;
    self.items = ko.observableArray(data);
    self.chunkedList = ko.computed(function() {
        var result = [];
        var chunk = [];
        self.items().forEach(function(item, index) {
            if (index % 4 === 0) {
                chunk = [];
                result.push(chunk);
            };
            chunk.push(item);
        });
        return result;
    });
};