You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:06:03