使用 *ngFor 索引将多个迭代分组在一行中

Use *ngFor index to group multiple iterations in one row

我一直在尝试构建一个包含多列的动态输入对话框。基本上有一个字段列表,我想为每两个字段构建一行。我的尝试看起来像这样(甚至不确定这是否可能)

<div *ngFor="let f of fields; let i = index">
    <div class="row" *ngIf="i % 2 = 1">
        <div *ngFor="let field of [fields[i],fields[i+1]]">
            <div class="col-3"><label>{{field.key}}</label></div>
            <div class="col-3"><input [(ngModel)]="object[field.key]"></div>
        </div>
    </div>
</div>

fields 是对象中所有字段的映射,如下所示:

[{key: fieldName,value: fieldValue},...]

很明显,因为我在这里,我的代码无法正常工作,我愿意接受有关其他实现的建议。

尝试更改此行

<div *ngFor="let f of fields" let i = index>

至此

<div *ngFor="let f of fields; let i = index">

这样试试:

<div *ngFor="let f of fields; let i = index">
    <div class="row" *ngIf="i % 2 === 1"> // === rather than =
        <div *ngFor="let field of [fields[i-1],fields[i]]"> // call previous element
            <div class="col-3"><label>{{field.key}}</label></div>
            <div class="col-3"><input [(ngModel)]="object[field.key]"></div>
        </div>
    </div>
</div>

首先,你必须在 ngIf 条件下使用等于运算符 此外,您的 child-HTML-code 必须依赖于奇数来不调用数组 (i - 1) 中不存在的位置。请记住,第一个索引值是 0

将其用于输入

<input [(ngModel)]="field.value" name="{{field.key}}" />

你的值在值属性

我能够用这个 html 实现这些列。只是在使用 CSS atm 时遇到了一些问题,所以它看起来还不是它应该的样子,但在结构上它现在是正确的。

<div class="ui-grid ui-grid-responsive ui-fluid" *ngIf="saveObject">
    <div *ngFor="let f of fields; let i = index">
        <div *ngIf="i % 2 === 1 && i < fields?.length" class="ui-grid-row">
            <div *ngFor="let field of [fields[i-1],fields[i]]">
                <div class="ui-grid-col-3 field-label"><label for="attribute">{{field.key}}</label></div>
                <div class="ui-grid-col-3">
                    <p-checkbox *ngIf="booleanFields.indexOf(field.key) !== -1" binary="true" [(ngModel)]="saveObject[field.key]"></p-checkbox>
                    <p-calendar *ngIf="dateFields.indexOf(field.key) !== -1" [(ngModel)]="saveObject[field.key]" dateFormat="yy-mm-dd" [showIcon]="true"></p-calendar>
                    <input *ngIf="(booleanFields.indexOf(field.key) === -1) && (dateFields.indexOf(field.key) === -1)" pInputText id="attribute" [(ngModel)]="saveObject[field.key]"/>
                </div>
            </div>
        </div>
        <div *ngIf="fields?.length % 2 === 1 && i === fields?.length - 1">
            <div *ngFor="let field of [fields[i]]">
                <div class="ui-grid-col-6 field-label"><label for="attributeEnd">{{field.key}}</label></div>
                <div class="ui-grid-col-6">
                    <p-checkbox *ngIf="booleanFields.indexOf(field.key) !== -1" binary="true" [(ngModel)]="saveObject[field.key]"></p-checkbox>
                    <p-calendar *ngIf="dateFields.indexOf(field.key) !== -1" [(ngModel)]="saveObject[field.key]" dateFormat="yy-mm-dd" [showIcon]="true"></p-calendar>
                    <input *ngIf="(booleanFields.indexOf(field.key) === -1) && (dateFields.indexOf(field.key) === -1)" pInputText id="attributeEnd" [(ngModel)]="saveObject[field.key]"/>
                </div>
            </div>
        </div>
    </div>
</div>

最后得到了一些重复的代码,可能会有更好的解决方案,但我现在会坚持这样做。 非常感谢所有回复的人。

简单的方法是将行数组预先计算成额外的 属性:

this.itemsPerRow = 2
this.rows = Array.from(
  Array(Math.ceil(this.fields.length / this.itemsPerRow)).keys()
)

然后在 HTML 中,您将使用两个带切片管道的循环:

<div *ngFor="let i of rows" class="row">
  <div *ngFor="let field of fields | slice:(i*itemsPerRow):(i+1)*itemsPerRow">
    <div class="col-3"><label>{{field.key}}</label></div>
    <div class="col-3"><input [(ngModel)]="object[field.key]"></div>
  </div>
</div>

演示: http://plnkr.co/edit/GVVyta1mqWAKP09V7Qvw?p=preview

修改后的 Jaroslaw 解决方案对我有用(每行 3 项):

<ng-container *ngFor="let a of array; let i = index">
    <div class="row" *ngIf="i % 3 === 0">
        <div *ngFor="let item of [array[i],array[i+1],array[i+2]]" class="col-md-4">
            <ng-container *ngIf="item">