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

Angular动态mat-table表单如何保存所有行 字段为空仅存最后行如何解决

问题根因

  • 你使用了单个FormGroup承载所有行的通信数据,所有行的输入控件都绑定到了同一组表单字段上,新增行时后续输入会覆盖之前的值,导致提交时仅保留最后一行数据。
  • 默认值不生效有两个原因:一是上述表单结构错误,二是getStandardValues方法中字段赋值映射错误,把kommunikationsnummer的取值错配为this.kType.kommunikationsort,同时响应式表单优先级高于你手动绑定的[value]属性,手动绑定的值不会生效。

修复方案

1. 修改Typescript代码

将communication字段从FormGroup改为FormArray,每一行对应独立的FormGroup实例:

import { FormArray, FormControl, FormGroup } from '@angular/forms';

persoForm = new FormGroup({
    // 改为FormArray承载多行数据
    communication: new FormArray([]),
    // 其他不相关代码保留
})

// 新增:获取通信表单数组的便捷方法
get communicationArr(): FormArray {
  return this.persoForm.get('communication') as FormArray
}

// 新增:创建单条通信记录的表单组
private createComItem(data?: any): FormGroup {
  return new FormGroup({
    kommunikationsart: new FormControl(data?.kommunikationsart?.bezeichnung ?? ''),
    kommunikationsort: new FormControl(data?.kommunikationsort?.bezeichnung ?? ''),
    kommunikationsnummer: new FormControl(data?.nummerAdresse ?? '')
  })
}

// 修改:新增行方法
addCom(defaultData?: any) {
  this.communicationArr.push(this.createComItem(defaultData))
  // 刷新mat-table数据源
  this.comdataSource.data = this.communicationArr.controls
}

// 修改:删除行方法
delCom(index: number) {
  this.communicationArr.removeAt(index)
  this.comdataSource.data = this.communicationArr.controls
}

// 修改:默认值赋值方法
getStandardValues(){
  // 单条默认值直接调用addCom传入即可
  this.addCom(this.kType)
  // 若接口返回多条默认值,循环添加即可:
  // this.apiData.forEach(item => this.addCom(item))
}

// 提交方法不变,打印的communication字段就是包含所有行数据的数组
onSubmit(){
   console.log(this.persoForm.getRawValue());
}

2. 修改HTML模板代码

移除冗余的formGroupName绑定,给每行绑定对应的FormGroup实例,删除手动绑定的[value]属性:

<div id="communicationTitle"> 
  <h3> Kommunikation </h3> 
  <button mat-button mat-stroked-button color="primary" (click)="addCom()" style="height: 35px; margin-top:10px; margin-left:10px;"> Hinzufügen </button> 
</div>
<div class="communicationTable" >
  <form [formGroup]="persoForm">
    <!-- 移除原来的formGroupName="communication" -->
    <table mat-table [dataSource]="comdataSource" #comTable>
      <ng-container matColumnDef="art">
        <th mat-header-cell *matHeaderCellDef> Art </th>
        <td mat-cell *matCellDef="let cType"> 
          <mat-form-field>
            <!-- 移除[value]绑定 -->
            <mat-select formControlName="kommunikationsart"> 
              <mat-option *ngFor="let auswahl of communicationKinds" [value]="auswahl.bezeichnung"> {{auswahl.bezeichnung}} </mat-option>
            </mat-select>
          </mat-form-field>
        </td>
      </ng-container>
      <ng-container matColumnDef="ort">
        <th mat-header-cell *matHeaderCellDef> Sorte </th>
        <td mat-cell *matCellDef="let cType"> 
          <mat-form-field>
            <!-- 移除[value]绑定 -->
            <mat-select formControlName="kommunikationsort"> 
              <mat-option *ngFor="let auswahl of communicationSorts" [value]="auswahl.bezeichnung"> {{auswahl.bezeichnung}} </mat-option>
            </mat-select>
          </mat-form-field>
        </td>
      </ng-container>
      <ng-container matColumnDef="address">
        <th mat-header-cell *matHeaderCellDef> Nummer/Adresse </th>
        <td mat-cell *matCellDef="let cType"> 
          <mat-form-field>
            <!-- 移除[value]绑定 -->
            <input matInput type="text" formControlName="kommunikationsnummer">
          </mat-form-field>
        </td>
      </ng-container>
      <!-- 其他列(call、复选框、删除)代码保持不变 -->
      <ng-container matColumnDef="details">
        <th mat-header-cell *matHeaderCellDef> Call </th>
        <td mat-cell *matCellDef="let cType">
          <button mat-icon-button color="primary" >
            <mat-icon class="mat-18">call</mat-icon>
          </button>
        </td>
      </ng-container>
      <ng-container matColumnDef="update">
        <th mat-header-cell *matHeaderCellDef> Std </th>
        <td mat-cell *matCellDef="let cType">
          <mat-checkbox></mat-checkbox>
        </td>
      </ng-container>
      <ng-container matColumnDef="delete">
        <th mat-header-cell *matHeaderCellDef> Delete </th>
        <td mat-cell *matCellDef="let cType; let i = index">
          <button mat-icon-button color="warn" (click)="delCom(i)">
            <mat-icon class="mat-18">delete</mat-icon>
          </button>
        </td>
      </ng-container>
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <!-- 给行绑定对应的FormGroup实例 -->
      <tr mat-row *matRowDef="let row; columns: displayedColumns;" [formGroup]="row"></tr>
    </table>
  </form> 
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:15:03