Angular中FormArray调用removeAt(i)无法删除指定索引项怎么解决?
问题根因
你遇到的删除失效/删错项的问题来自两个核心错误:
- *ngFor遍历的数据源是你自行维护的
nameDriver普通数组,调用FormArray.removeAt()只会修改表单控件数组,不会同步更新这个普通数组,导致渲染索引错位,看起来删除操作没有生效。 - 同时使用响应式表单的
formControlName和模板驱动的[(ngModel)]双向绑定,二者状态独立不同步,也会引发值和渲染的冲突,Angular官方不推荐两种表单模式混用。
修复步骤
1. 组件代码调整
首先给FormArray添加便捷getter,删除时同步更新自定义数组,添加trackBy函数优化列表渲染避免索引错乱:
// 新增:便捷获取nameDriver表单数组 get nameDriverControl(): FormArray { return this.driverInfoForm.get('nameDriver') as FormArray; } // 优化删除方法 removeDriver(i: number) { this.nameDriverControl.removeAt(i); // 同步更新你自行维护的普通数组 this.nameDriver.splice(i, 1); } // 新增:ngFor跟踪函数,避免列表重绘时索引错位 trackByIndex(index: number, item: any): number { return index; // 如果表单项有唯一标识字段,优先返回唯一值:return item.get('id').value }
2. HTML代码调整
修改遍历对象为表单数组的controls,删除多余的ngModel绑定,给操作按钮补充type属性避免默认触发表单提交:
<form [formGroup]="driverInfoForm"> <div class="row" formArrayName="nameDriver"> <div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12 d-flex" [formGroupName]="i" *ngFor="let driver of nameDriverControl.controls; let i=index; trackBy: trackByIndex"> <label>{{i+1}}.Name</label> <input class="form-control" type="text" id="name" name="name{{i}}" formControlName="name"><br/> <label>{{i+1}}.Owner Id</label> <input class="form-control" type="text" id="ownerId" name="ownerId{{i}}" inputmode="numeric" dashFormat formControlName="ownerId" maxLength="14"> <div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2" > <div class="form-group mb-0" *ngIf="i !== 0"> <button class="btn btn-danger" (click)="removeDriver(i)" type="button"> Delete </button> </div> <div class="form-group mb-2"> <button *ngIf="i >= 0 && i < 1" type="button" [hidden]="nameDriver.length > 3" (click)="addDriver()" class="btn btn-primary"> Add </button> </div> </div> </div> </div> </form>
可选优化
如果你不需要单独维护nameDriver普通数组,可以完全依赖响应式表单的值,删除所有和nameDriver数组相关的操作,直接通过this.nameDriverControl.value获取所有表单项的值即可,不需要手动同步两个数据源。
内容的提问来源于stack exchange,提问作者Fash
相关产品推荐
相关产品推荐

