Angular 5:如何获取表格动态增删行的输入值及总价
嘿,我看你现在的问题出在**所有行都用了相同的formControlName**上——Angular里每个表单控件的名字是唯一的,所以你新增的行其实都绑定到同一个值,自然没法单独获取每一行的输入。得换成FormArray来处理这种动态行的场景,这才是Angular表单设计里用来管理动态控件集合的正确方式。
第一步:重构组件的表单逻辑(TS代码)
先导入表单相关模块,然后用FormArray来存储每一行的表单数据,每一行对应一个包含code、name、price的FormGroup:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, FormArray, FormControl } from '@angular/forms'; @Component({ selector: 'app-your-component', templateUrl: './your-component.component.html', styleUrls: ['./your-component.component.css'] }) export class YourComponent implements OnInit { addForm: FormGroup; constructor(private fb: FormBuilder) { } ngOnInit(): void { // 初始化表单,默认先添加一行数据 this.addForm = this.fb.group({ items: this.fb.array([this.createItem()]) }); } // 创建单个行的表单组 createItem(): FormGroup { return this.fb.group({ code: [''], name: [''], price: [''] }); } // 快捷获取FormArray的方法,模板里会用到 get items(): FormArray { return this.addForm.get('items') as FormArray; } // 新增一行 addFieldValue(): void { this.items.push(this.createItem()); } // 删除指定索引的行 deleteFieldValue(index: number): void { this.items.removeAt(index); } // 计算所有行的总价 calculateTotal(): number { let total = 0; // 遍历每一行的价格,累加有效数值 this.items.controls.forEach(item => { const price = parseFloat(item.get('price')?.value || '0'); if (!isNaN(price)) { total += price; } }); return total; } // 提交表单时获取所有数据 onSubmit(): void { if (this.addForm.valid) { const allRowData = this.addForm.value.items; console.log('所有行的输入数据:', allRowData); const totalPrice = this.calculateTotal(); console.log('计算出的总价:', totalPrice); // 这里可以添加后续的业务逻辑,比如提交到后端 } } }
第二步:修改模板的表格结构(HTML代码)
把原来的循环改成遍历FormArray的控件,给每一行绑定对应的formGroupName,确保每一行的输入都是独立的:
<form class="form-horizontal" (ngSubmit)="onSubmit()" [formGroup]="addForm"> <table> <!-- 遍历所有动态行 --> <tr *ngFor="let item of items.controls; let i = index" [formGroupName]="i"> <td><input type="text" formControlName="code" placeholder="输入编码"></td> <td><input type="text" formControlName="name" placeholder="输入名称"></td> <td><input type="number" formControlName="price" placeholder="输入价格"></td> <td><button type="button" (click)="deleteFieldValue(i)">Delete</button></td> </tr> <!-- 添加新行的按钮 --> <tr> <td colspan="4"> <button type="button" (click)="addFieldValue()">Add more</button> </td> </tr> <!-- 实时显示总价 --> <tr> <td colspan="3" align="right"><strong>总价:</strong></td> <td>{{ calculateTotal() }}</td> </tr> <!-- 提交按钮 --> <tr> <td colspan="4"> <button type="submit">提交数据</button> </td> </tr> </table> </form>
关键说明
[formGroupName]="i":把当前行和FormArray中对应索引的FormGroup绑定,确保每一行的输入互不干扰。- 把价格输入改成
type="number":既符合输入场景,也能避免用户输入非数字内容。 calculateTotal()方法:会自动遍历所有行的价格,处理空值或非数字的情况,确保计算准确。
这样改完之后,你点击Add more新增的每一行都会有独立的表单控件,提交时可以通过this.addForm.value.items拿到所有行的完整数据,总价也能实时计算显示了。
内容的提问来源于stack exchange,提问作者Dhawal Mhatre
相关产品推荐
相关产品推荐

