当试图创建一系列无序列表时,Knockoutjs抛出异常。

时间:2023-01-02 21:17:24

I'm attempting to create a series of <ul> tags using the foreach: context. The goal is to iterate through the list, and start a new <ul> for every 4th item. My code so far is:

我尝试使用foreach: context来创建一系列

    标记。目标是遍历列表,并为每4个项目启动一个新的
      。到目前为止,我的代码是:

<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>

When I do this, I get the exception:

当我这样做时,我得到一个例外:

Microsoft JScript runtime error: Cannot find closing comment tag to match: ko if: ($index() % 4 == 0)

Microsoft JScript运行时错误:无法找到匹配的结束注释标签:ko if: ($index() % 4 == 0)

It seems to not like the </li><li> content within the if comment block, probably because the DOM parser is scratching its head on how to actually parse this. If I change it to:

它似乎不喜欢if注释块中的

  • 内容,这可能是因为DOM解析器在如何解析这个问题上抓到了头。如果我把它改成:

  • 内容,这可能是因为DOM解析器在如何解析这个问题上抓到了头。如果我把它改成:
  • <!-- ko if: ($index() % 4 == 0) -->
    <li>Fake!</li>
    <!-- /ko -->
    

    Then it'll work perfectly (that is, create a fake <li> every 4th element.

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

  • )。

  • )。
  • I'm open to other ideas of accomplishing this as well. Thanks!

    我也愿意接受其他的想法。谢谢!

    1 个解决方案

    #1


    3  

    Yeah, the initial DOM (before Knockout activates) is illegal, and Knockout doesn't work by pasting HTML into the DOM, it actually copies it into a javascript DOM object, which it inserts into the DOM. </ul><ul> isn't a legal object, so Knockout won't be able to turn it into a template. Even if it could, the foreach binding is on the original <ul>, not the new one started by the if, so the Knockout code that added items would still be operating on the first list.

    是的,初始DOM(在Knockout激活之前)是非法的,而Knockout并不是通过将HTML粘贴到DOM中来工作的,而是将其复制到一个javascript DOM对象中,并将其插入到DOM中。

      不是一个合法的对象,所以Knockout不能把它变成一个模板。即使它可以,foreach绑定也在原始的
        ,而不是由if启动的新版本,所以添加项目的Knockout代码仍然在第一个列表中运行。

    So, in summation, Knockout's foreach and template bindings don't work by building HTML as if it's a string.

    因此,在求和中,Knockout的foreach和模板绑定都不能像字符串一样构建HTML。

    You will need a more complex solution.

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

    Something like this would work, but I don't know if this is still what you are going for:

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

    <!-- 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;
        });
    };
    

    #1


    3  

    Yeah, the initial DOM (before Knockout activates) is illegal, and Knockout doesn't work by pasting HTML into the DOM, it actually copies it into a javascript DOM object, which it inserts into the DOM. </ul><ul> isn't a legal object, so Knockout won't be able to turn it into a template. Even if it could, the foreach binding is on the original <ul>, not the new one started by the if, so the Knockout code that added items would still be operating on the first list.

    是的,初始DOM(在Knockout激活之前)是非法的,而Knockout并不是通过将HTML粘贴到DOM中来工作的,而是将其复制到一个javascript DOM对象中,并将其插入到DOM中。

      不是一个合法的对象,所以Knockout不能把它变成一个模板。即使它可以,foreach绑定也在原始的
        ,而不是由if启动的新版本,所以添加项目的Knockout代码仍然在第一个列表中运行。

    So, in summation, Knockout's foreach and template bindings don't work by building HTML as if it's a string.

    因此,在求和中,Knockout的foreach和模板绑定都不能像字符串一样构建HTML。

    You will need a more complex solution.

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

    Something like this would work, but I don't know if this is still what you are going for:

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

    <!-- 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;
        });
    };