Angular响应式表单嵌套FormArray无报错但功能不生效问题求助
核心问题分析
你的嵌套FormArray功能异常的核心原因是没有正确关联外层info项和内层size数组的实例,具体问题如下:
- 原
sizesgetter逻辑完全错误:newInfo是每次调用都会返回全新FormGroup的getter,你通过sizesgetter拿到的size数组,和页面上渲染的任意info项内部的size数组都不是同一个实例,所有针对sizes的操作都不会作用到页面绑定的表单上 - 模板内层循环数据源错误:内层size循环直接使用全局的
sizes.controls,没有绑定到当前外层循环的info实例 - 操作方法没有关联对应外层项:
addSizes/removeSizes没有指定操作哪个info下的size数组 - 删除逻辑不规范:直接操作FormArray的controls数组splice,没有使用Angular官方提供的
removeAtAPI,容易出现表单状态不同步问题 - 循环索引重名:内外层循环都用
i作为索引变量,会出现变量覆盖问题
修正后的实现代码
组件TypeScript代码修改
// 移除原来错误的 get sizes() 方法 // 修改addSizes,接收要操作的info项索引 addSizes(infoIndex: number) { const currentInfo = this.infos.at(infoIndex) as FormGroup; const currentSizeArr = currentInfo.get('size') as FormArray; currentSizeArr.push(this.newSize); } // 修改removeSizes,接收info项索引和要删除的size项索引 removeSizes(infoIndex: number, sizeIndex: number) { const currentInfo = this.infos.at(infoIndex) as FormGroup; const currentSizeArr = currentInfo.get('size') as FormArray; currentSizeArr.removeAt(sizeIndex); currentSizeArr.updateValueAndValidity(); } // 修改removeInfos,用官方API删除 removeInfos(i: number) { this.infos.removeAt(i); this.infos.updateValueAndValidity(); }
原有其他代码无需修改。
模板HTML代码修改
<fieldset formArrayName="infoProduct" class="mb-3"> <div class="row"> <!-- 外层info循环索引改名为infoIndex,避免和内层索引冲突 --> <fieldset class="col-md-12" name="size" *ngFor="let info of infos.controls; let infoIndex = index" style="vertical-align: middle" [formGroupName]="infoIndex"> <div formArrayName="size" class="mb-3"> <!-- 内层size循环数据源改为当前info实例下的size数组,索引起名为sizeIndex --> <fieldset class="col-md-12" name="size" *ngFor="let zise of (info.get('size') as FormArray).controls; let sizeIndex = index" style="vertical-align: middle" [formGroupName]="sizeIndex"> <div class="row"> <div class="col-md-6 form-group"> <input type="number" class="form-control" id="size" name="size" placeholder="Tamaño" formControlName="size" /> </div> </div> <div class="col-md-6 form-group"> <input type="number" class="form-control" id="stock" name="stock" placeholder="Stock" formControlName="stock" /> </div> <div class="form-group"> <a class="genric-btn info-border small" (click)="removeSizes(infoIndex, sizeIndex)"> <mdb-icon fas icon="minus-circle"></mdb-icon>Eliminar </a> </div> </fieldset> <!-- 添加size时传入当前info的索引 --> <a class="genric-btn info-border small" (click)="addSizes(infoIndex)"> <mdb-icon far icon="plus-square"></mdb-icon>Agregar </a> </div> <div class="form-group"> <ckeditor [editor]="Editor" [config]="config" data="data" formControlName="description"> </ckeditor> </div> <div class="row"> <div class="col-md-6 form-group"> <color-circle formControlName="color"></color-circle> </div> <div class="col-md-6 form-group"> <input type="number" class="form-control" id="price" name="price" placeholder="Precio" formControlName="price" /> </div> </div> <div class="form-group"> <input type="file" class="form-control" id="image" name="image" (change)="cargarImagen($event, infoIndex)" /> </div> <div class="form-group"> <a class="genric-btn info-border small" (click)="removeInfos(infoIndex)"> <mdb-icon fas icon="minus-circle"></mdb-icon>Eliminar </a> </div> <hr> </fieldset> </div> <a class="genric-btn info-border small" (click)="addInfos()"> <mdb-icon far icon="plus-square"></mdb-icon>Agregar </a> </fieldset>
修改后即可实现正常的嵌套FormArray增删功能,表单字段也会正常生成。
内容的提问来源于stack exchange,提问作者cesdav
相关产品推荐
相关产品推荐

