【问题标题】:Knockout.js using foreach and $index with if bindingKnockout.js 使用 foreach 和 $index 与 if 绑定
【发布时间】:2021-07-04 12:28:19
【问题描述】:

我正在尝试显示迭代列表中的元素,该列表按 3 乘 3 分组。我使用了 $index 的值,但我不知道为什么看起来不正确。

<div class="row" data-bind="foreach: displaySel">
     <div class="col-md-2">
          <!--ko if: $index() % 3 === 0-->
          <div data-bind="attr:{id: 'div_'+$index()}">
          <!--/ko -->
               <div data-bind="attr:{id: 'g_'+$data.hId}" style="position:relative;">
                    <div>other things here</div>
               </div>
          <!--ko if: ($index() % 3 === 2 || $index() === displaySel.length - 1)-->
          </div>
          <!--/ko -->
    </div>
</div>

第一个 div 应该在第一个元素信息之前打开并在第三个元素信息之后关闭。第二个 div 将在第四个之前打开并在另外三个之后关闭,依此类推,直到列表结束。这里最好的方法是什么?

【问题讨论】:

    标签: javascript html knockout.js


    【解决方案1】:

    您不能(或者不应该,我忘记了)真正以这样的命令方式使用 Knockout,您可以手动生成或不生成开始/结束标签。相反,您需要正确嵌套。

    换句话说,将&lt;!-- ko if: ... --&gt;&lt;!-- /ko --&gt; 视为正确的结束/结束标记,它们总是需要环绕完整 元素。

    换一种说法,你正在尝试做同样的事情:

    <div>
      Some content
      <strong>
        <div>
      </strong>
    
          CONTENT
    
      <strong>
        </div>
      </strong>
    </p>
    

    也许 Knockout 应该给你一个错误,但是(我猜本着 HTML 的精神)它试图充分利用它。

    因此,您应该在视图模型中执行“分组”逻辑。额外的好处是您也可以对其进行单元测试。这是一个例子:

    const chunkSize = 3;
    
    class RootVm {
      displaySel = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25];
      displaySelGroups = ko.computed(() =>
        // Chunk in groups of 3 based on:
        // https://stackoverflow.com/a/44687374/419956
        [...Array(Math.ceil(this.displaySel.length / chunkSize))].map(_ => this.displaySel.splice(0,chunkSize))
      );
    }
    
    ko.applyBindings(new RootVm());
    .col-2 { background: silver; border: 1px solid black; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css" integrity="sha512-P5MgMn1jBN01asBgU0z60Qk4QxiXo86+wlFahKrsQf37c9cro517WzVSPPV1tDKzhku2iJ2FVgL67wG03SGnNA==" crossorigin="anonymous" />
    
    <div class="row" data-bind="foreach: displaySelGroups">
      <div class="col-2" data-bind="foreach: $data">
        <div data-bind="attr:{id: 'div_'+$index()}">
          <div data-bind="attr:{id: 'g_'+$data.hId}" style="position:relative;">
            <div data-bind="text: $data"></div>
          </div>
        </div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 2012-07-04
      • 2012-07-14
      • 1970-01-01
      • 2015-02-18
      • 2016-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多