You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 07:41:35