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

Angular中点击按钮时如何保存动态生成的多个表单数据到数据库

Angular中点击按钮时如何保存动态生成的多个表单数据到数据库

我看了你的代码,发现几个关键问题导致你没法把动态表单的数据成功保存到数据库,咱们一步步来调整:


1. 修正组件的提交逻辑:传递正确的数据格式

你现在的提交方法里,错误地把FormGroup数组直接传给了服务,但后端需要的是纯数据数组。另外你有两个重复的提交方法,我们可以整合为一个清晰的逻辑:

修改你的FetchDataComponent代码:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // 别忘了导入Validators
import { AnimalService } from '../animal.service';

@Component({
  selector: 'app-fetch-data',
  templateUrl: './fetch-data.component.html',
})
export class FetchDataComponent implements OnInit {
  reactForm: FormGroup;
  public forms: FormGroup[] = [];
  public unitData: Object[] = [
    { Id: 'Form1', Form: '1' },
    { Id: 'Form2', Form: '2' },
    { Id: 'Form3', Form: '3' },
    { Id: 'Form4', Form: '4' },
    { Id: 'Form5', Form: '5' },
  ];
  public val: string = "1";
  public unitFields: Object = { text: 'Form', value: 'Form' };
  public unitWaterMark: string = '';

  ngOnInit(): void {
    this.generateForms(1);
  }

  generateForms(count: number): void {
    this.forms = [];
    for (let i = 0; i < count; i++) {
      this.forms.push(
        this.fb.group({
          Id: [0],
          Animal: [null, Validators.required], // 增加必填验证
          Tagno: [null, Validators.required], // 增加必填验证
        })
      )
    }
  }

  dropdownChange(args: any): void {
    const selectedCount = parseInt(args.value, 10);
    if (!isNaN(selectedCount)) {
      this.generateForms(selectedCount);
    }
  }

  // 统一的提交方法
  onSubmitAll() {
    let allValid = true;
    // 遍历表单,收集数据同时做验证
    const allFormData = this.forms.map(form => {
      if (!form.valid) {
        form.markAllAsTouched();
        allValid = false;
      }
      return form.value;
    });

    if (allValid) {
      // 调用服务提交纯数据数组
      this.service.postOffspring(allFormData).subscribe({
        next: (response) => {
          console.log('所有表单数据保存成功!', response);
          // 成功后可以重置表单
          this.generateForms(1);
          this.val = "1";
        },
        error: (error) => {
          console.error('保存失败,请检查后端接口', error);
          alert('保存失败,请稍后重试');
        }
      });
    } else {
      alert('请填写所有必填字段!');
    }
  }

  constructor(private fb: FormBuilder, private service: AnimalService ) {}
}

2. 调整服务的POST方法:支持接收数组

你的服务现在是按单个对象接收的,我们要改成支持接收多个表单的数据数组:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Offspring } from './animal';

@Injectable({ providedIn: 'root' })
export class AnimalService {
  readonly Urloffspring = 'api/AnimalAPI';

  constructor(private http:HttpClient) { }

  formOffspring:Offspring = new Offspring();
  formSubmitted: boolean = false;

  // 改成接收Offspring数组
  postOffspring(offspringList: Offspring[]){
    console.log('要提交的数组:', offspringList);
    return this.http.post<Offspring[]>(this.Urloffspring, offspringList);
  }
}

同时确保你的Offspring模型类包含所有表单字段:

export class Offspring {
  Id: number;
  Animal: string;
  Tagno: string;

  constructor() {
    this.Id = 0;
    this.Animal = '';
    this.Tagno = '';
  }
}

3. 给HTML加提交按钮和验证提示

在动态表单循环结束后,添加统一的提交按钮,同时给输入框加错误提示:

<div class="col-lg-12 control-section">
  <div class="content-wrapper" style="max-width: 600px; margin: 0 auto;">
    <ejs-dropdownlist id="Unt" 
                      [dataSource]="unitData" 
                      type="text" 
                      name="Unt" 
                      [fields]="unitFields" 
                      placeholder="选择表单数量" 
                      (change)="dropdownChange($event)" 
                      floatLabelType="Auto" 
                      [value]="val" >
    </ejs-dropdownlist><br><br>

    <div *ngFor="let form of forms; let i = index">
      <form [id]="'formId' + i" [formGroup]="form" class="form-horizontal" novalidate>
        <div class="form-title">
          <span>表单 {{ i + 1 }}</span>
        </div>

        <div class="form-group">
          <div class="e-float-input">
            <input [id]="'Id' + i" formControlName="Id" />
            <span class="e-float-line"></span>
            <label [for]="'Id' + i" class="e-float-text">ID</label>
          </div>
        </div>

        <div class="form-group">
          <div class="e-float-input">
            <input [id]="'Animal' + i" type="text" formControlName="Animal" />
            <span class="e-float-line"></span>
            <label [for]="'Animal' + i" class="e-float-text">Animal</label>
            <!-- 验证错误提示 -->
            <div *ngIf="form.get('Animal')?.invalid && (form.get('Animal')?.touched || form.get('Animal')?.dirty)" class="text-danger">
              Animal为必填项
            </div>
          </div>
        </div>

        <div class="form-group">
          <div class="e-float-input">
            <input [id]="'Tagno' + i" type="text" formControlName="Tagno" />
            <span class="e-float-line"></span>
            <label [for]="'Tagno' + i" class="e-float-text">Tagno</label>
            <!-- 验证错误提示 -->
            <div *ngIf="form.get('Tagno')?.invalid && (form.get('Tagno')?.touched || form.get('Tagno')?.dirty)" class="text-danger">
              Tagno为必填项
            </div>
          </div>
        </div>
      </form>
    </div>

    <!-- 统一提交按钮 -->
    <button type="button" (click)="onSubmitAll()" class="btn btn-primary mt-3">保存所有表单</button>
  </div>
</div>

4. 完善后端API:支持批量插入

补全你的后端Controller,支持批量接收数据并插入数据库(假设用EF Core):

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Project1.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Project1.Controllers
{
    [Route("api/AnimalAPI")] // 和前端服务的URL保持一致
    [ApiController]
    public class AnimalAPIController : ControllerBase
    {
        private readonly YourDbContext _dbContext; // 替换成你的数据库上下文

        public AnimalAPIController(YourDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        [HttpPost]
        public async Task<IActionResult> PostOffspringList([FromBody] List<Offspring> offspringList)
        {
            if (offspringList == null || offspringList.Count == 0)
            {
                return BadRequest("没有要保存的数据");
            }

            // 批量添加到数据库
            await _dbContext.Offsprings.AddRangeAsync(offspringList);
            await _dbContext.SaveChangesAsync();

            return Ok(offspringList); // 返回保存后的数据
        }
    }
}

如果前端和后端端口不同,别忘了在后端Program.cs配置跨域:

var builder = WebApplication.CreateBuilder(args);

// 跨域配置
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

builder.Services.AddControllers();
builder.Services.AddDbContext<YourDbContext>(options => 
    options.UseSqlServer(builder.Configuration.GetConnectionString("YourConnectionString")));

var app = builder.Build();

app.UseHttpsRedirection();
app.UseCors("AllowAll"); // 启用跨域
app.UseAuthorization();
app.MapControllers();

app.Run();

做完这些调整后,你选择下拉数量、填写表单,点击保存按钮,就能把所有表单的数据批量提交到后端并插入数据库了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 12:33:06