Angular中如何动态计算表格每行输入值总和并显示在最后单元格
Angular动态表格行实时求和解决方案
问题背景
需要为动态生成的表格每行计算多个输入框(Labour、Price、SGST、CGST、Discount)的数值总和,实时显示在该行的Final Amount单元格中,表格行数随产品数量动态变化。现有代码存在输入值变更时总和始终显示0、无法动态更新的问题。
现有HTML代码
<table class="table table-striped table-bordered table-hover"> <thead> <tr> <th scope="col">#</th> <th scope="col">Product Category</th> <th scope="col">Sub Category</th> <th scope="col">Master Category</th> <th scope="col">Product Weight</th> <th scope="col">Labour</th> <th scope="col">Price</th> <th scope="col">SGST (In %)</th> <th scope="col">CGST (In %)</th> <th scope="col">Discount</th> <th scope="col">Final Amount</th> </tr> </thead> <tbody> <tr *ngFor="let item of _selectedProductsData;index as i"> <th scope="row">{{i+1}}</th> <td>{{item.productCategory}}</td> <td>{{item.subCategory}}</td> <td>{{item.masterCategory}}</td> <td>{{item.productWeight}} gms</td> <td> <input class="form-control labourInput" type="number" id="{{item.productGuid}}-labour" placeholder="Enter Labour"> </td> <td> <input class="form-control priceInput" type="number" id="{{item.productGuid}}-price" placeholder="Enter Price"> </td> <td> <input class="form-control sgstInput" type="number" id="{{item.productGuid}}-SGST" placeholder="Enter SGST"> </td> <td> <input class="form-control cgstInput" type="number" id="{{item.productGuid}}-CGST" placeholder="Enter CGST"> </td> <td> <input class="form-control discountInput" type="number" id="{{item.productGuid}}-discount" placeholder="Enter Discount"> </td> <td> {{calculateTotalAmountOfEachProduct(item.productGuid)}} </td> </tr> </tbody> </table>
现有TypeScript代码
calculateTotalAmountOfEachProduct(productGuid:string):number { let labourInput = Number((<HTMLInputElement>document.getElementById(`${productGuid}-labour`)).value) let priceInput = Number((<HTMLInputElement>document.getElementById(`${productGuid}-price`)).value) let sgstInput = Number((<HTMLInputElement>document.getElementById(`${productGuid}-SGST`)).value) let cgstInput = Number((<HTMLInputElement>document.getElementById(`${productGuid}-CGST`)).value) let discountInput = Number((<HTMLInputElement>document.getElementById(`${productGuid}-discount`)).value) return labourInput+priceInput+sgstInput+cgstInput+discountInput }
问题原因
- 直接通过
document.getElementById操作DOM获取输入值,不符合Angular数据驱动的设计理念。 - 输入值变更时未触发Angular的变更检测机制,导致视图无法更新总和。
- 未将输入值与组件数据模型绑定,无法追踪值的变化。
解决方案
步骤1:扩展产品数据模型,添加输入字段属性
在获取到_selectedProductsData后,为每个产品对象添加对应输入字段的属性,初始值设为0:
// 数据加载完成后处理 this._selectedProductsData.forEach(item => { item.labour = 0; item.price = 0; item.sgst = 0; item.cgst = 0; item.discount = 0; });
步骤2:使用双向数据绑定绑定输入框
修改HTML中的输入框,使用Angular的[(ngModel)]双向绑定将输入值与产品模型的属性关联:
<tbody> <tr *ngFor="let item of _selectedProductsData;index as i"> <th scope="row">{{i+1}}</th> <td>{{item.productCategory}}</td> <td>{{item.subCategory}}</td> <td>{{item.masterCategory}}</td> <td>{{item.productWeight}} gms</td> <td> <input class="form-control labourInput" type="number" [(ngModel)]="item.labour" placeholder="Enter Labour"> </td> <td> <input class="form-control priceInput" type="number" [(ngModel)]="item.price" placeholder="Enter Price"> </td> <td> <input class="form-control sgstInput" type="number" [(ngModel)]="item.sgst" placeholder="Enter SGST"> </td> <td> <input class="form-control cgstInput" type="number" [(ngModel)]="item.cgst" placeholder="Enter CGST"> </td> <td> <input class="form-control discountInput" type="number" [(ngModel)]="item.discount" placeholder="Enter Discount"> </td> <td> {{ calculateTotal(item) }} </td> </tr> </tbody>
步骤3:修改求和方法,基于数据模型计算
不再操作DOM,直接从产品模型中取数值计算总和,同时处理可能的NaN情况:
calculateTotal(item: any): number { // 处理空值或非数字的情况,默认取0 const labour = isNaN(item.labour) ? 0 : item.labour; const price = isNaN(item.price) ? 0 : item.price; const sgst = isNaN(item.sgst) ? 0 : item.sgst; const cgst = isNaN(item.cgst) ? 0 : item.cgst; const discount = isNaN(item.discount) ? 0 : item.discount; // 提示:若SGST/CGST是百分比(如输入12代表12%),需转换为实际金额,示例: // const taxAmount = (labour + price) * ((sgst + cgst) / 100); // return (labour + price + taxAmount) - discount; // 以下按原需求直接相加,可根据业务逻辑调整 return labour + price + sgst + cgst + discount; }
步骤4:导入FormsModule
使用ngModel需要在组件所属的模块中导入FormsModule:
import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ // ...其他已导入的模块 FormsModule ] }) export class YourComponentModule { }
原理说明
通过双向数据绑定[(ngModel)],输入值的变更会自动同步到组件的产品模型中,Angular会自动触发变更检测,实时更新视图中的总和计算结果。这种方式符合Angular数据驱动的设计模式,代码更易维护、测试,也避免了直接操作DOM带来的问题。
内容的提问来源于stack exchange,提问作者Snake_Eyes
相关产品推荐
相关产品推荐

