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
相关产品推荐
相关产品推荐

