【发布时间】:2021-10-29 20:58:26
【问题描述】:
我想在一个对象数组上运行一个 ngFor,以便用每个对象对应的数据填充标签,并且最好在同一个 ngFor 中,我想为上述数组中的每个对象添加一个表单控件。我还希望能够为每个添加的新对象添加一个新的表单控件。据我了解,执行上述操作的逻辑一切正常,我的问题是能够同时适当地循环对象数组和表单控件数组?
下面是为数组中的每个对象创建一个新的表单控件的逻辑:
首先,我在 ngOnInit 的 FormGroup 中初始化了 FormArray,如下所示:
stockForm: FormGroup;
ngOnInit(): void {
this.stockForm = new FormGroup({
'quantities': new FormArray([])
})
this.getBranchStock();
}
然后我声明了两种方法,一种用于获取控件,另一种用于为上述 FormArray 创建控件。
提到的第一种方法(获取控件):
getQuantityControls() {
return (<FormArray>this.stockForm.get('quantities')).controls;
}
然后,提到的第二种方法(创建控件):
createNewQuantity() {
const quantity = new FormControl('', [Validators.required]);
(<FormArray>this.stockForm.get('quantities')).push(quantity)
}
第二种方法“createNewQuantity”,将一个新的表单控件推送到表单数组。当我收到我之前谈到的对象数组时,最初会调用此方法。我通过 for 循环运行数组中的每个对象来调用“createNewQuantity”方法,如下所示:
product: BranchProduct[];
getBranchStock() {
const id = this.branchService.getBranchId();
id.subscribe(
(resp: any) => {
this.subs.add(this.branchService.getBranchStock(resp).subscribe(
(resp: any) => {
this.product = resp;
for (var i = 0; i < this.product.length; i++) {
this.createNewQuantity();
}
},
(error: HttpErrorResponse) => {
console.log(error);
})
)
})
}
上述执行后,我对数组中的每个对象都有一个表单控件。这按预期工作(据我所知)。我真正的问题在于我运行 ngFor 循环的方式。如上所示,我需要遍历“产品”数组中的所有对象,以及“数量”FormArray 中的每个新创建的表单控件。我不知道如何设置模板以使其正常工作。我尝试过的如下:
<form [formGroup]="stockForm" *ngIf="stockForm">
<mat-card *ngFor="let item of product; let quantity of getQuantityControls(); let i = index;" class="enter-quantity-card">
<mat-grid-list cols="5" rowHeight="7:1">
<!-- Product Id Tile-->
<mat-grid-tile>
<div class="data-wrapper">
<h3>Product ID: <span class="data-text"><strong>{{item.ProductId}}</strong></span></h3>
</div>
</mat-grid-tile>
<!-- Product Type Tile -->
<mat-grid-tile>
<div class="data-wrapper">
<h3>Product Type: <span class="data-text"><strong>{{item.ProductTypeName}}</strong></span></h3>
</div>
</mat-grid-tile>
<!-- Product Name Tile-->
<mat-grid-tile>
<div class="data-wrapper">
<h3>Product Name: <span class="data-text"><strong>{{item.ProductName}}</strong></span></h3>
</div>
</mat-grid-tile>
<!-- Quantity On Hand Tile-->
<mat-grid-tile>
<div class="data-wrapper">
<h3>Quantity on Hand: <span class="data-text"><strong>{{item.QuantityOnHand}}</strong></span>
</h3>
</div>
</mat-grid-tile>
<!-- Quantity Selected Tile (Using Form Array) -->
<mat-grid-tile>
<mat-form-field>
<input matInput [formControlName]="i">
</mat-form-field>
</mat-grid-tile>
</mat-grid-list>
</mat-card>
</form>
由于我在 ONE ngFor 中同时拥有 let item of product 和 let quantity of getQuantityControls(); let i = index; 声明,因此上述内容不起作用。 Typescript 不允许这样做,因为新的 AbstractControl 不能是产品数组类型。但是,我根本不知道如何构建模板以使其正常工作。表单本身看起来像这样:
如您所见,每个对象“都有自己的”表单控件。但是我不知道如何使每个表单控件独一无二,以便分别验证每个控件。任何帮助表示赞赏。
【问题讨论】:
-
如何使用
index而不是循环遍历product数组来获取每个产品?你会有一个循环:*ngFor="let quantity of getQuantityControls(); let i = index;",然后像这样使用索引:{{product[i].ProductTypeName}} -
这很棒。简单的解决方法,非常感谢。我还需要在 ngFor 所在的同一
mat-card标签中添加formArrayName = "quantities"。如果您愿意,可以发表您的评论作为答案,我很乐意接受!
标签: arrays angular typescript forms ngfor