如何根据多个 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>
标签一样。
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
: 推 Id
s 1 和 2 的项目
moreThanTwo
:推送Id
大于2 的item
每次原始 forArray
发生变化时,都会重新计算 groupedArray
。您可以通过将 Ronaldo
的 Id
输入更改为 5 来对此进行测试。该项目将移出 fieldset
.
在form-horizontal
div
中使用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>
我想在 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>
标签一样。
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
: 推Id
s 1 和 2 的项目
moreThanTwo
:推送Id
大于2 的item
每次原始 forArray
发生变化时,都会重新计算 groupedArray
。您可以通过将 Ronaldo
的 Id
输入更改为 5 来对此进行测试。该项目将移出 fieldset
.
在form-horizontal
div
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>