Angular表格多行输入数据转JSON:仅捕获首行的问题求助
解决Angular多行词汇录入表单转JSON的问题
嘿,我完全懂你的困扰——原来的单组表单只能捕获一行数据,要实现多行词汇录入并转成JSON,Angular的FormArray就是专门用来处理这种动态表单组的工具!我给你一步步拆解实现方法:
1. 重构组件中的表单结构
首先我们要把原来的单个FormGroup改成包含FormArray的表单结构,用来存储多行词汇的表单组。
组件代码示例:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'; @Component({ selector: 'app-word-refactor', templateUrl: './word-refactor.component.html', styleUrls: ['./word-refactor.component.css'] }) export class WordRefactorComponent implements OnInit { refactorForm: FormGroup; constructor(private formBuilder: FormBuilder) { } ngOnInit(): void { // 初始化表单,包含一个存储词汇行的FormArray,默认添加一行 this.refactorForm = this.formBuilder.group({ words: this.formBuilder.array([this.createWordGroup()]) }); } // 创建单个词汇行的FormGroup,保留原有的必填验证 private createWordGroup(): FormGroup { return this.formBuilder.group({ word_to_rename: [null, Validators.required], renowned_word: [null, Validators.required] }); } // 方便模板访问FormArray的getter,简化代码 get wordsArray(): FormArray { return this.refactorForm.get('words') as FormArray; } // 添加新的词汇行 addWordRow(): void { this.wordsArray.push(this.createWordGroup()); } // 删除指定索引的词汇行(至少保留一行,避免空表) removeWordRow(index: number): void { if (this.wordsArray.length > 1) { this.wordsArray.removeAt(index); } } // 提交表单并转换为JSON格式 submitForm(): void { if (this.refactorForm.valid) { // 直接获取所有行数据并转成JSON const jsonData = JSON.stringify(this.refactorForm.value); console.log('录入的词汇JSON:', jsonData); // 这里可以将jsonData发送到后端或做其他业务处理 } else { // 表单验证不通过时,标记所有控件为已触碰,触发错误提示 this.refactorForm.markAllAsTouched(); } } }
2. 模板中的表格渲染与表单绑定
接下来在HTML模板中,我们需要遍历FormArray的控件,为每一行绑定对应的表单组,并添加添加/删除行的按钮:
模板代码示例:
<form [formGroup]="refactorForm" (ngSubmit)="submitForm()"> <table border="1"> <thead> <tr> <th>原词汇</th> <th>目标词汇</th> <th>操作</th> </tr> </thead> <tbody formArrayName="words"> <!-- 遍历每一行的FormGroup,绑定索引作为表单组名称 --> <tr *ngFor="let wordGroup of wordsArray.controls; let i = index" [formGroupName]="i"> <td> <input type="text" formControlName="word_to_rename" placeholder="请输入原词汇" [class.invalid]="wordsArray.at(i).get('word_to_rename')?.invalid && wordsArray.at(i).get('word_to_rename')?.touched" > <span *ngIf="wordsArray.at(i).get('word_to_rename')?.invalid && wordsArray.at(i).get('word_to_rename')?.touched" style="color: red;"> 原词汇为必填项 </span> </td> <td> <input type="text" formControlName="renowned_word" placeholder="请输入目标词汇" [class.invalid]="wordsArray.at(i).get('renowned_word')?.invalid && wordsArray.at(i).get('renowned_word')?.touched" > <span *ngIf="wordsArray.at(i).get('renowned_word')?.invalid && wordsArray.at(i).get('renowned_word')?.touched" style="color: red;"> 目标词汇为必填项 </span> </td> <td> <button type="button" (click)="removeWordRow(i)" *ngIf="wordsArray.length > 1">删除</button> </td> </tr> </tbody> </table> <div style="margin-top: 10px;"> <button type="button" (click)="addWordRow()">添加新行</button> <button type="submit" [disabled]="!refactorForm.valid">提交并生成JSON</button> </div> </form>
3. 核心逻辑说明
- FormArray的作用:它可以动态管理多个
FormGroup,完美适配表格的多行录入需求; - getter
wordsArray:简化模板中对FormArray的访问,不用每次都写冗长的this.refactorForm.get('words'); - 表单验证:每行的两个字段都保留了
Validators.required,只有所有行的必填项都填完,提交按钮才会启用; - JSON转换:提交时直接通过
this.refactorForm.value获取所有行的数据,再用JSON.stringify()就能得到标准的JSON格式,示例输出如下:{"words":[{"word_to_rename":"旧词1","renowned_word":"新词1"},{"word_to_rename":"旧词2","renowned_word":"新词2"}]}
这样你就能实现多行词汇的录入,并轻松转换成JSON格式啦!
内容的提问来源于stack exchange,提问作者Maria Gálvez
相关产品推荐
相关产品推荐

