如何为Angular表格准备数据?分组时遇国家重复问题求助
Angular 实现按产品类型+国家二次分组的层级表格
问题核心
现有包含country、productType、year等字段的数据集,已实现按productType的一级分组,但二次按country分组时,不同产品类型下会出现重复国家,需要优化分组逻辑并渲染出指定的层级表格结构。
示例数据集
const rawData = [ { country: 'China', productType: 'Phone', year: 2023, sales: 1000 }, { country: 'China', productType: 'Laptop', year: 2023, sales: 500 }, { country: 'US', productType: 'Phone', year: 2023, sales: 800 }, { country: 'US', productType: 'Laptop', year: 2023, sales: 600 }, { country: 'Japan', productType: 'Phone', year: 2023, sales: 400 }, ];
目标表格结构
- 一级分组:产品类型
- 二级分组:国家
- 明细列:年份、销量等
解决方案
1. 优化二次分组逻辑
核心是先按产品类型分组,再在每个产品组内部按国家分组,这样每个产品类型下的国家仅包含该产品有数据的条目,不会跨产品重复。实现嵌套分组函数:
// 通用分组工具函数 groupBy<T>(array: T[], key: keyof T): Record<string, T[]> { return array.reduce((result, item) => { const groupKey = item[key] as string; result[groupKey] = result[groupKey] || []; result[groupKey].push(item); return result; }, {} as Record<string, T[]>); } // 生成嵌套分组数据:产品类型 -> 国家 -> 明细 getNestedGroupedData() { // 先按产品类型一级分组 const productGroups = this.groupBy(this.rawData, 'productType'); // 对每个产品组内的数据再按国家二次分组 return Object.entries(productGroups).map(([productType, productData]) => ({ productType, countryGroups: Object.entries(this.groupBy(productData, 'country')).map(([country, countryData]) => ({ country, details: countryData })) })); }
2. 模板渲染层级表格
用Angular的*ngFor嵌套渲染,结合rowspan合并单元格实现层级展示,避免重复内容:
<table border="1" cellpadding="8" style="border-collapse: collapse;"> <thead> <tr> <th>产品类型</th> <th>国家</th> <th>年份</th> <th>销量</th> </tr> </thead> <tbody> <!-- 遍历产品类型分组 --> <ng-container *ngFor="let productGroup of nestedGroupedData"> <!-- 遍历该产品下的国家分组 --> <ng-container *ngFor="let countryGroup of productGroup.countryGroups; let countryIdx = index"> <!-- 国家分组的第一行,合并产品类型单元格 --> <tr> <td *ngIf="countryIdx === 0" [attr.rowspan]="productGroup.countryGroups.length"> {{ productGroup.productType }} </td> <!-- 合并国家单元格,覆盖该国家下的所有明细行 --> <td [attr.rowspan]="countryGroup.details.length"> {{ countryGroup.country }} </td> <!-- 第一行明细 --> <td>{{ countryGroup.details[0].year }}</td> <td>{{ countryGroup.details[0].sales }}</td> </tr> <!-- 同一国家下的剩余明细行 --> <tr *ngFor="let detail of countryGroup.details.slice(1)"> <td></td> <td></td> <td>{{ detail.year }}</td> <td>{{ detail.sales }}</td> </tr> </ng-container> </ng-container> </tbody> </table>
3. 关键注意点
- 不要先全局按国家分组再关联产品类型,必须在产品类型分组内部做国家分组,从根源避免跨产品的国家重复。
- 使用
rowspan合并单元格时,要准确计算合并的行数(对应分组内的子项数量),避免表格结构错乱。
内容的提问来源于stack exchange,提问作者Dalama
相关产品推荐
相关产品推荐

