Angular如何在ngFor中同时渲染对象数据与动态生成的FormControl
解法说明
你出现报错的核心原因是ngFor不支持同时遍历两个数组,结合你已经保证业务数组product和FormArray的长度完全对齐的前提,通过索引匹配即可实现需求,不需要同时遍历两个数组。
1. 组件类优化
首先优化组件代码,避免在模板中反复调用方法获取控件数组,提升渲染性能:
import { AbstractControl } from '@angular/forms'; // 新增类属性,直接存储控件数组的引用 quantityControls: AbstractControl[]; ngOnInit(): void { this.stockForm = new FormGroup({ 'quantities': new FormArray([]) }) // 初始化时绑定控件数组引用,后续FormArray新增/删除元素时该引用会自动同步 this.quantityControls = (this.stockForm.get('quantities') as FormArray).controls; this.getBranchStock(); }
2. 模板修正
需要补充formArrayName指令绑定你的quantities表单数组,同时简化ngFor写法,仅遍历业务数组,通过索引匹配对应表单控件:
<form [formGroup]="stockForm" *ngIf="stockForm"> <!-- 绑定FormArray名称,作为内部formControlName的上下文 --> <ng-container formArrayName="quantities"> <mat-card *ngFor="let item of product; 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-error *ngIf="quantityControls[i].hasError('required') && quantityControls[i].touched"> 请输入必填数量 </mat-error> </mat-form-field> </mat-grid-tile> </mat-grid-list> </mat-card> </ng-container> </form>
3. 后续新增逻辑同步
后续新增业务对象时,只要同步操作两个数组即可保持对应关系:
addNewProduct(newProduct: BranchProduct) { // 新增业务对象 this.product.push(newProduct); // 同步新增表单控件 this.createNewQuantity(); }
内容的提问来源于stack exchange,提问作者SeventhWarhawk
相关产品推荐
相关产品推荐

