2

我正在尝试使用上下文创建一系列<ul>标签。foreach:目标是遍历列表,并为每第 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 if: ($index() % 4 == 0)

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

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

然后它会完美地工作(也就是说,<li>每 4 个元素创建一个假的。

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

4

1 回答 1

3

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

因此,总而言之,Knockoutforeachtemplate绑定无法像构建字符串一样构建 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;
    });
};
于 2013-07-26T22:42:46.250 回答