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

ngFor循环中输入框输入同步变更如何修复及ngFor数据绑定方法

问题描述

使用Angular的ngFor循环生成输入框时,在任意一个输入框输入内容,其余所有输入框内容都会同步变更,异常效果如下:
问题效果截图

原始代码

HTML代码

<mat-expansion-panel  class="childPanel" [expanded]="true" hideToggle disabled style=" background:#F2EDFF;" *ngFor="let i of listSousCategorie">
  <div class="childPanel_body2 mat-badge-large" fxLayout="row" fxFlex fxLayoutAlign="start center">
    <div style="padding-left:1em" fxFlex="grow" >{{i.libelle}} {{i.id}}</div>
    <mat-form-field>
      <form [formGroup]="form" (ngSubmit)="onSubmit(i.id)">
        <mat-label>Note</mat-label>
        <input  type="text" matInput  formControlName="Note" [(ngModel)]="Note" >
      </form>
    </mat-form-field>
  </div>
</mat-expansion-panel>

TS代码

Note:string;

ngOnInit() {
  this.form = this.formBuilder.group({
    Note: [''],
  });
}

onSubmit(id:number) {
  let obj = this.form.value;
  obj.Note = this.Note;

  console.log(this.Note)
  this.LExamenSousCategorieService.updateSouCategorie(obj,id).then(res => {
  })
} 
问题原因
  • 所有循环生成的输入框都共享同一个全局Note变量和同一个FormGroup实例,双向绑定的数据源完全一致,修改一个自然会同步到所有输入框
  • 同时使用formControlName和ngModel属于Angular不推荐的混合用法,v6+版本默认会抛出警告,也容易引发逻辑冲突
修复方案

提供两种常用修复方案,可根据业务场景选择:

方案一:绑定到单条数据属性(适合简单无校验场景)

无需使用响应式表单,直接将输入值绑定到每个循环项自身的属性,每个项维护独立的输入值:

TS修改

// 删除全局Note变量声明和全局form的初始化代码
onSubmit(id:number, currentNote: string) {
  const obj = { Note: currentNote };
  console.log(currentNote);
  this.LExamenSousCategorieService.updateSouCategorie(obj,id).then(res => {});
}

HTML修改

<mat-expansion-panel  class="childPanel" [expanded]="true" hideToggle disabled style=" background:#F2EDFF;" *ngFor="let i of listSousCategorie">
  <div class="childPanel_body2 mat-badge-large" fxLayout="row" fxFlex fxLayoutAlign="start center">
    <div style="padding-left:1em" fxFlex="grow" >{{i.libelle}} {{i.id}}</div>
    <mat-form-field>
      <form (ngSubmit)="onSubmit(i.id, i.note)">
        <mat-label>Note</mat-label>
        <input type="text" matInput [(ngModel)]="i.note" [ngModelOptions]="{standalone: true}">
      </form>
    </mat-form-field>
  </div>
</mat-expansion-panel>

方案二:使用FormArray(适合需要表单校验的复杂场景)

用FormArray为每个循环项创建独立的FormGroup,符合响应式表单最佳实践:

TS修改

noteFormArray: FormArray;

ngOnInit() {
  // 为每个列表项生成独立的FormGroup存入FormArray
  this.noteFormArray = this.formBuilder.array(
    this.listSousCategorie.map(() => 
      this.formBuilder.group({ Note: [''] })
    )
  );
}

onSubmit(id:number, index: number) {
  const obj = this.noteFormArray.at(index).value;
  console.log(obj.Note);
  this.LExamenSousCategorieService.updateSouCategorie(obj,id).then(res => {});
}

HTML修改

<mat-expansion-panel  class="childPanel" [expanded]="true" hideToggle disabled style=" background:#F2EDFF;" *ngFor="let i of listSousCategorie; let index = index">
  <div class="childPanel_body2 mat-badge-large" fxLayout="row" fxFlex fxLayoutAlign="start center">
    <div style="padding-left:1em" fxFlex="grow" >{{i.libelle}} {{i.id}}</div>
    <mat-form-field>
      <form [formGroup]="noteFormArray.at(index)" (ngSubmit)="onSubmit(i.id, index)">
        <mat-label>Note</mat-label>
        <input type="text" matInput formControlName="Note">
      </form>
    </mat-form-field>
  </div>
</mat-expansion-panel>
注意事项
  • 不要混合使用formControlName和ngModel,二者选其一即可,避免逻辑冲突
  • 循环生成的表单控件必须对应独立的数据源,不能所有项共享同一个全局变量或同一个FormGroup实例

内容的提问来源于stack exchange,提问作者drnwork

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:15:02