文章目录
-
- 场景说明
- 方法一:在模板中直接计算(推荐用于简单逻辑)
-
- [HTML 模板(Angular + ng-zorro-antd 示例)](#HTML 模板(Angular + ng-zorro-antd 示例))
- 方法二:在数据源中预处理(推荐用于复杂或复用逻辑)
-
- [在 TypeScript 中提前计算好新字段](#在 TypeScript 中提前计算好新字段)
- 模板中直接使用
- 方法三:使用自定义管道(Pipe)------适用于可复用的格式化逻辑
- [方法四:使用 nzCustomColumn 或 render 函数(高级用法)](#方法四:使用 nzCustomColumn 或 render 函数(高级用法))
- [举一反三: 避免的反模式](#举一反三: 避免的反模式)
- 总结
- [示例完整代码(Angular + ng-zorro)](#示例完整代码(Angular + ng-zorro))
场景说明
在使用 th-table(通常指基于 Angular 的 ng-zorro-antd 或类似 UI 库中的表格组件)时,如果某一列的值需要通过两个字段(key)计算得出,你可以通过以下几种方式实现展示:
假设你的数据结构如下:
ts
list = [
{ name: '张三', price: 100, quantity: 5 },
{ name: '李四', price: 80, quantity: 3 }
];
你想在表格中展示一列 "总价" = price × quantity。
方法一:在模板中直接计算(推荐用于简单逻辑)
HTML 模板(Angular + ng-zorro-antd 示例)
html
<nz-table #basicTable [nzData]="list">
<thead>
<tr>
<th>姓名</th>
<th>单价</th>
<th>数量</th>
<th>总价</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of basicTable.data">
<td>{{ item.name }}</td>
<td>{{ item.price }}</td>
<td>{{ item.quantity }}</td>
<td>{{ item.price * item.quantity }}</td> <!-- 直接计算 -->
</tr>
</tbody>
</nz-table>
优点 :简单直观,适合轻量计算。
注意:避免在模板中写复杂逻辑(如函数调用、循环),会影响性能和可读性。
方法二:在数据源中预处理(推荐用于复杂或复用逻辑)
在 TypeScript 中提前计算好新字段
ts
this.list = originalData.map(item => ({
...item,
total: item.price * item.quantity // 新增 total 字段
}));
模板中直接使用
html
<td>{{ item.total }}</td>
优点:
- 模板干净;
- 支持排序、搜索(如果表格支持);
- 逻辑集中,便于测试和维护。
方法三:使用自定义管道(Pipe)------适用于可复用的格式化逻辑
创建管道
ts
@Pipe({ name: 'multiply' })
export class MultiplyPipe implements PipeTransform {
transform(a: number, b: number): number {
return a * b;
}
}
模板中使用
html
<td>{{ item.price | multiply: item.quantity }}</td>
适用场景 :乘法、百分比、货币格式等通用计算。
不推荐:仅用于当前表格的特定业务逻辑(过度设计)。
方法四:使用 nzCustomColumn 或 render 函数(高级用法)
如果你使用的是支持 自定义渲染 的表格(如 Ant Design Vue / React),但在 Angular 的 nz-table 中,也可以通过 *nzCell 自定义单元格:
html
<td *nzCell="let item">
<span class="highlight">{{ item.price * item.quantity }}</span>
</td>
或者结合方法:
html
<td>{{ getTotal(item) }}</td>
并在组件中定义方法:
ts
getTotal(item: any): number {
return item.price * item.quantity;
}
注意 :在 Angular 中,模板中调用方法会频繁触发变更检测 ,可能导致性能问题。仅建议用于简单、无副作用的计算,或配合 OnPush 策略使用。
举一反三: 避免的反模式
html
<!-- 不推荐:在模板中调用复杂函数 -->
<td>{{ calculateTotal(item) }}</td>
ts
// 每次变更检测都会执行,影响性能
calculateTotal(item) {
// 复杂逻辑...
return item.a * item.b + someExpensiveOperation();
}
总结
| 场景 | 推荐方案 |
|---|---|
| 简单计算(如 a + b, a * b) | 模板内直接计算 {``{ a * b }} |
| 复杂/可复用逻辑 | 数据预处理(.map() 添加字段) |
| 通用格式化(如货币、百分比) | 自定义 Pipe |
| 需要高亮、图标等富 UI | 使用 *nzCell 自定义单元格 |
示例完整代码(Angular + ng-zorro)
ts
// component.ts
list = [
{ name: '张三', price: 100, quantity: 5 },
{ name: '李四', price: 80, quantity: 3 }
].map(item => ({
...item,
total: item.price * item.quantity
}));
html
<!-- template.html -->
<nz-table [nzData]="list">
<thead>
<tr><th>姓名</th><th>单价</th><th>数量</th><th>总价</th></tr>
</thead>
<tbody>
<tr *ngFor="let item of list">
<td>{{ item.name }}</td>
<td>{{ item.price }}</td>
<td>{{ item.quantity }}</td>
<td>{{ item.total }}</td>
</tr>
</tbody>
</nz-table>