如何根据多个 if 条件对 foreach 内的项目进行分组

How to group items inside foreach based on multiple if conditions

我想在 form-horizontal 中循环我的 form-group 使用来自淘汰赛的 foreach。我有条件 Id 是 1 和 2,这应该在 <fieldset> 内分组。我已经尝试过当只有 1 个条件正常工作时,但是当多个 1 和 2 时它不工作。

代码示例:

<div class="form-horizontal" data-bind="foreach: forArray()">
<!-- ko if: Id() === 1 -->
<fieldset>
    <legend>
        Foo
    </legend>
    <!-- /ko -->
    <!-- ko if: Id() === 1 || Id() === 2 -->
    <div class="form-group">
        <label class="control-label col-sm-5"><span data-bind="html: NameColumn"></span></label>
        <div class="col-sm-7">
            <input type="text" data-bind="value: Id" />
        </div>
    </div>
    <!-- /ko -->
    <!-- ko if: Id() === 2 -->
</fieldset>
<br />
<!-- /ko -->

<!-- ko if: Id() !== 1 && Id() !== 2 -->
<div class="form-group">
    <label class="control-label col-sm-5"><span data-bind="html: NameColumn"></span></label>
    <div class="col-sm-7">
        <input type="text" data-bind="value: Id" />
    </div>
</div>
<!-- /ko -->

看起来你的 ko-/ko 标签对有点乱

如果条件 Id() === 1 有效,您记下的内容 <fieldset> 将打开,但如果 Id() === 2

将关闭

首先,您的无容器控制流语法 将不起作用。您应该将它们视为真正的 html 容器元素,就像使用 <div> 标签一样。

来自documentation

The <!-- ko --> and <!-- /ko --> comments act as start/end markers, defining a “virtual element” that contains the markup inside. Knockout understands this virtual element syntax and binds as if you had a real container element.

即使您修正了语法,它也不会显示您想要的输出。通过 forArray 的单个循环无法创建此功能,因为它会为 Id 1 和 2 创建多个 fieldset 元素。因此,您需要创建一个 computed 属性。此计算 属性 将具有 2 个数组属性:

  • lessThanTwo: 推 Ids 1 和 2
  • 的项目
  • moreThanTwo:推送Id大于2
  • 的item

每次原始 forArray 发生变化时,都会重新计算 groupedArray。您可以通过将 RonaldoId 输入更改为 5 来对此进行测试。该项目将移出 fieldset.

form-horizontaldiv

中使用with binding to create a new binding context

const viewModel = function() {
  const self = this;

  self.forArray = ko.observableArray([
  { NameColumn: '<u>Messi</u>', Id: ko.observable(1) },
  { NameColumn: '<b>Ronaldo</b>', Id: ko.observable(2) },
  { NameColumn: '<i>Griezmann</i>', Id: ko.observable(3) },
  { NameColumn: '<u>Mbappé</u>', Id: ko.observable(4) }
  ]);

  self.groupedArray = ko.computed(() => {
    const groupedObject = {
      lessThanTwo: [],
      moreThanTwo: []
    };

    self.forArray().forEach(item => {
      // if Id() > 2 push it a moreThanTwo property
      // otherwise push it to lessThanTwo property
      if (item.Id() == 1 || item.Id() == 2)
        groupedObject.lessThanTwo.push(item);
      else
        groupedObject.moreThanTwo.push(item);
    })

    return groupedObject;
  })
}

ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="form-horizontal" data-bind="with: groupedArray">
  <fieldset>
    <legend>
      Foo
    </legend>
    <!-- ko foreach: lessThanTwo -->
    <div class="form-group">
      <label class="control-label col-sm-5"><span data-bind="html: NameColumn"></span></label>
      <div class="col-sm-7">
        <input type="text" data-bind="value: Id" />
      </div>
    </div>
    <!-- /ko -->

  </fieldset>
  <br />
 <!-- ko foreach: moreThanTwo -->
  <div class="form-group">
    <label class="control-label col-sm-5"><span data-bind="html: NameColumn"></span></label>
    <div class="col-sm-7">
      <input type="text" data-bind="value: Id" />
    </div>
  </div>
 <!-- /ko -->
</div>