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

Angular表格表单数据保存异常:如何实现所有行数据批量存储至数据库

解决Angular表格表单多行数据保存问题

我看了你的代码,问题很明确:你当前的saveEDT()方法只在保存单个edt对象的数据,而表格里已经添加的行数据都存在TabArray数组里,完全没被处理,所以只有最后一行(绑定到edt的那行)的数据被存到数据库了。

下面是具体的修复步骤和修改后的代码:

第一步:修改saveEDT()方法,处理所有行数据

我们需要把TabArray里的每一行数据,加上最后一行未点击添加的edt数据(如果有填写内容的话),一起发送给后端服务。这里分两种场景处理:

场景1:后端支持批量插入(推荐)

如果你的后端接口支持一次性接收多条数据,直接把整个数组发过去效率更高:

saveEDT(): void {
  // 先把已添加的行和最后一行未提交的行合并
  const allRows = [...this.TabArray];
  // 只有当最后一行有填写内容时才加入数组
  if (this.edt.enseignantname || this.edt.heure1 || this.edt.heure2 || this.edt.heure3 || this.edt.heure4) {
    allRows.push(this.edt);
  }

  if (allRows.length === 0) {
    console.log("没有数据需要保存");
    return;
  }

  // 调用批量保存接口(需要在EdtService中新增对应方法)
  this.edtService.createEdtBatch(allRows)
    .subscribe(
      response => {
        console.log("所有数据保存成功", response);
        this.submitted = true;
        // 保存后清空表单
        this.TabArray = [];
        this.edt = {};
      },
      error => {
        console.log("保存失败", error);
      });
}

同时在EdtService中添加批量保存方法:

createEdtBatch(edtList: any[]): Observable<any> {
  // 替换成你的实际批量接口地址
  return this.http.post(`${this.apiBaseUrl}/edt/batch`, edtList);
}

场景2:后端只支持单条插入

如果后端没有批量接口,就遍历数组逐个发送请求:

// 记得导入forkJoin
import { forkJoin } from 'rxjs';

saveEDT(): void {
  const allRows = [...this.TabArray];
  if (this.edt.enseignantname || this.edt.heure1 || this.edt.heure2 || this.edt.heure3 || this.edt.heure4) {
    allRows.push(this.edt);
  }

  if (allRows.length === 0) {
    console.log("没有数据需要保存");
    return;
  }

  // 生成所有保存请求的数组
  const saveRequests = allRows.map(row => this.edtService.createEdt(row));
  // 用forkJoin同时发送所有请求
  forkJoin(saveRequests)
    .subscribe(
      responses => {
        console.log("所有行保存成功", responses);
        this.submitted = true;
        this.TabArray = [];
        this.edt = {};
      },
      error => {
        console.log("某一行保存失败", error);
      });
}

第二步:修复HTML里的小错误

你的HTML里有两处细节问题会导致表单异常:

  1. 循环里的mat-option错误使用了food变量,实际应该是enseignant
  2. 输入框的name属性用了动态值{{field.heure1}},空值时会导致ngModel报错,改成带索引的固定名称

修改后的HTML表格部分:

<table class="table table-bordered">
 <thead>
 <tr>
 <th>Enseignant</th>
 <th>07h15-09h15</th>
 <th>09h15-11h15</th>
 <th>12h30-14h00</th>
 <th>14h00-15h30</th>
 <th>Action</th>
 </tr>
 </thead>
 <tbody>
 <tr *ngFor="let field of TabArray; let i = index">
 <td>
 <mat-form-field appearance="outline">
 <mat-select [(ngModel)]="field.enseignantname" name="enseignant-{{i}}">
 <mat-option *ngFor="let enseignant of enseignants" [value]="enseignant.value">
 {{enseignant.viewValue}}
 </mat-option>
 </mat-select>
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input [(ngModel)]="field.heure1" matInput type="text" name="heure1-{{i}}" />
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input [(ngModel)]="field.heure2" matInput type="text" name="heure2-{{i}}" />
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input [(ngModel)]="field.heure3" matInput type="text" name="heure3-{{i}}" />
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input [(ngModel)]="field.heure4" matInput type="text" name="heure4-{{i}}" />
 </mat-form-field>
 </td>
 <td>
 <button mat-icon-button class="deletebutton" color="warn" type="button" (click)="deleteFieldValue(i)">
 <mat-icon>delete</mat-icon>
 </button>
 </td>
 </tr>
 <tr>
 <td>
 <mat-form-field appearance="outline">
 <mat-select id="formEnseignant" [(ngModel)]="edt.enseignantname" name="form-enseignant">
 <mat-option *ngFor="let enseignant of enseignants" [value]="enseignant.value">
 {{enseignant.viewValue}}
 </mat-option>
 </mat-select>
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input matInput type="text" id="formHeure1" [(ngModel)]="edt.heure1" name="form-heure1" />
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input matInput type="text" id="formHeure2" [(ngModel)]="edt.heure2" name="form-heure2" />
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input matInput type="text" id="formHeure3" [(ngModel)]="edt.heure3" name="form-heure3" />
 </mat-form-field>
 </td>
 <td>
 <mat-form-field appearance="outline">
 <input matInput type="text" id="formHeure4" [(ngModel)]="edt.heure4" name="form-heure4" />
 </mat-form-field>
 </td>
 <td>
 <button mat-icon-button class="addbutton" color="primary"type="button" (click)="addFieldValue()">
 <mat-icon>add</mat-icon>
 </button>
 </td>
 </tr>
 </tbody>
</table>

第三步:可选优化:添加表单验证

如果需要确保每一行都填写了必要信息,可以在保存前做简单验证:

saveEDT(): void {
  const allRows = [...this.TabArray];
  if (this.edt.enseignantname || this.edt.heure1 || this.edt.heure2 || this.edt.heure3 || this.edt.heure4) {
    allRows.push(this.edt);
  }

  // 检查每一行是否填写了教师名称
  const invalidRows = allRows.filter(row => !row.enseignantname);
  if (invalidRows.length > 0) {
    alert("请填写所有行的教师名称");
    return;
  }

  // 后续保存逻辑...
}

这样修改后,点击保存按钮时,表格里的所有行(包括最后一行未点击添加的)都会被保存到数据库了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:07:44