Angular中如何实现表格每行Price与输入Quantity相乘计算总额
问题
希望实现表格中每条数据的Price与对应行输入的Quantity相乘,再结合折扣、税费计算每行的实际金额,最终汇总得出总金额。以下是当前的HTML和TS代码,请问如何修改实现需求?
当前HTML代码
<mat-table [dataSource]="dataSource" class="mat-elevation-z8"> <!-- adding Quantity and calculation stuff--> <ng-container matColumnDef="itemName1"> <mat-header-cell *matHeaderCellDef> Item-Name </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.itemName1 | uppercase}} </mat-cell> </ng-container> <ng-container matColumnDef="price1"> <mat-header-cell *matHeaderCellDef> Price </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.price1}} </mat-cell> </ng-container> <ng-container matColumnDef="discount1"> <mat-header-cell *matHeaderCellDef> Discount </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.discount1 | percent}} </mat-cell> </ng-container> <ng-container matColumnDef="tax1"> <mat-header-cell *matHeaderCellDef> Tax </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.tax1 | percent}} </mat-cell> </ng-container> <ng-container matColumnDef="quantity1"> <mat-header-cell *matHeaderCellDef> Quantity </mat-header-cell> <mat-cell *matCellDef="let element"> <mat-form-field class="example-width" appearance="outline"> <mat-label>Quantity</mat-label> <input matInput type="number" [formControl]="quNnumber"> </mat-form-field></mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> </mat-table> <h2>your Gross Total is : {{result}}</h2>
当前TS代码
const ELEMENT_DATA: PeriodicElement[] = [ {itemName1 : 'Asus' , quantity1 : '' , price1: 300 , discount1 : 0.07 , tax1 : 0.04 }, {itemName1 : 'Apple' , quantity1 : '' , price1: 600 , discount1 : 0.03 , tax1 : 0.07 }, {itemName1 : 'Samsung' , quantity1 : '' , price1: 500 , discount1 : 0.05 , tax1 : 0.01 }, ]; @Component({ selector: 'app-dialog', templateUrl: './dialog.component.html', styleUrls: ['./dialog.component.css'] }) export class DialogComponent implements OnInit { // table stuff displayedColumns: string[] = ['itemName1', 'price1', 'discount1','tax1','quantity1']; dataSource = new MatTableDataSource(ELEMENT_DATA); quNnumber = new FormControl(''); pricenumber = new FormControl(''); result!: number; Addnumber(){ // this.result = parseInt(this.pricenumber) * parseInt(this.quNnumber); } }
解决方案
核心问题分析
当前代码的核心问题是所有行的Quantity输入框绑定了同一个全局FormControl,无法区分每行的输入值,也就没法和对应行的Price关联计算。需要给每行数据单独绑定数量控制,同时实现实时计算总额的逻辑。
修改步骤
1. 调整TS代码
- 移除全局的
quNnumber和pricenumber,改为给每行数据添加独立的FormControl存储数量输入值 - 实现实时计算总金额的方法,监听每个数量输入的变化
- 完善包含折扣、税费的金额计算逻辑
修改后的TS代码:
import { Component, OnInit } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; import { FormControl } from '@angular/forms'; interface PeriodicElement { itemName1: string; quantity1: FormControl; price1: number; discount1: number; tax1: number; } const ELEMENT_DATA: PeriodicElement[] = [ { itemName1: 'Asus', quantity1: new FormControl(0), price1: 300, discount1: 0.07, tax1: 0.04 }, { itemName1: 'Apple', quantity1: new FormControl(0), price1: 600, discount1: 0.03, tax1: 0.07 }, { itemName1: 'Samsung', quantity1: new FormControl(0), price1: 500, discount1: 0.05, tax1: 0.01 }, ]; @Component({ selector: 'app-dialog', templateUrl: './dialog.component.html', styleUrls: ['./dialog.component.css'] }) export class DialogComponent implements OnInit { displayedColumns: string[] = ['itemName1', 'price1', 'discount1', 'tax1', 'quantity1', 'rowTotal']; dataSource = new MatTableDataSource(ELEMENT_DATA); result!: number; ngOnInit(): void { // 监听每个数量输入框变化,实时计算总额 this.dataSource.data.forEach(item => { item.quantity1.valueChanges.subscribe(() => { this.calculateTotal(); }); }); // 初始化计算一次总额 this.calculateTotal(); } // 计算每行实际金额并汇总总额 calculateTotal(): void { this.result = this.dataSource.data.reduce((total, item) => { const quantity = item.quantity1.value || 0; // 计算逻辑:(原价-折扣)* (1+税费) * 数量 const rowTotal = (item.price1 * (1 - item.discount1)) * (1 + item.tax1) * quantity; return total + rowTotal; }, 0); } }
2. 调整HTML代码
- 将Quantity输入框绑定到当前行元素的
quantity1FormControl - 添加
rowTotal列,显示每行的实际金额 - 修正表格行的语法错误
修改后的HTML代码:
<mat-table [dataSource]="dataSource" class="mat-elevation-z8"> <!-- Item-Name Column --> <ng-container matColumnDef="itemName1"> <mat-header-cell *matHeaderCellDef> Item-Name </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.itemName1 | uppercase}} </mat-cell> </ng-container> <!-- Price Column --> <ng-container matColumnDef="price1"> <mat-header-cell *matHeaderCellDef> Price </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.price1}} </mat-cell> </ng-container> <!-- Discount Column --> <ng-container matColumnDef="discount1"> <mat-header-cell *matHeaderCellDef> Discount </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.discount1 | percent}} </mat-cell> </ng-container> <!-- Tax Column --> <ng-container matColumnDef="tax1"> <mat-header-cell *matHeaderCellDef> Tax </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.tax1 | percent}} </mat-cell> </ng-container> <!-- Quantity Column --> <ng-container matColumnDef="quantity1"> <mat-header-cell *matHeaderCellDef> Quantity </mat-header-cell> <mat-cell *matCellDef="let element"> <mat-form-field class="example-width" appearance="outline"> <mat-label>Quantity</mat-label> <input matInput type="number" [formControl]="element.quantity1" min="0"> </mat-form-field> </mat-cell> </ng-container> <!-- Row Total Column --> <ng-container matColumnDef="rowTotal"> <mat-header-cell *matHeaderCellDef> Row Total </mat-header-cell> <mat-cell *matCellDef="let element"> {{(element.price1 * (1 - element.discount1)) * (1 + element.tax1) * (element.quantity1.value || 0) | number:'1.2-2'}} </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> </mat-table> <h2>your Gross Total is : {{result | number:'1.2-2'}}</h2>
关键说明
- 每行数量输入框绑定到对应行元素的
quantity1FormControl,确保输入值与行数据一一对应 - 通过
valueChanges监听数量输入变化,实时触发总额计算 - 金额计算逻辑:先扣除折扣,再叠加税费,最后乘以数量得到每行实际金额,再汇总所有行金额得到总额
- 使用
number管道格式化金额为两位小数,提升可读性
内容的提问来源于stack exchange,提问作者Firefly0027
相关产品推荐
相关产品推荐

