You need to enable JavaScript to run this app. Angular中如何遍历对象,使用*ngFor实现按section分组的UI渲染
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何遍历对象,使用*ngFor实现按section分组的UI渲染

核心实现逻辑

你当前拿到的是扁平化排布的条目数组,如果直接遍历整个数组,无法把同属一个section的条目归入同一个区块容器中。正确的实现方式是先在组件逻辑层把扁平数组按section字段做分组,转换成嵌套的结构化数据,再通过两层*ngFor完成渲染,这种写法逻辑清晰,变更检测性能好,也不会出现区块错位的问题。

第一步:组件侧完成分组转换

不要在模板里写临时判断逻辑做分组,直接在组件初始化、数据更新时完成分组计算。参考实现代码:

import { Component, OnInit } from '@angular/core';

// 原始数据类型定义
interface RawListItem {
  number: number;
  section: string;
}

// 分组后的数据结构
interface GroupedSection {
  sectionName: string;
  items: RawListItem[];
}

@Component({
  selector: 'app-section-list',
  templateUrl: './section-list.component.html'
})
export class SectionListComponent implements OnInit {
  // 你提供的原始扁平条目数组
  rawList: RawListItem[] = [
    { "number": 1, "section": "Section 1" },
    { "number": 2, "section": "Section 1" },
    { "number": 3, "section": "Section 1" },
    { "number": 1, "section": "Section 2" },
    { "number": 2, "section": "Section 2" },
    { "number": 1, "section": "Section 3" },
    { "number": 1, "section": "Section 4" },
    { "number": 2, "section": "Section 4" }
  ];

  // 存储分组后的结构化数据,供模板渲染
  groupedSections: GroupedSection[] = [];

  ngOnInit(): void {
    this.groupedSections = this.groupItemsBySection(this.rawList);
  }

  // 按section字段分组的通用方法
  private groupItemsBySection(list: RawListItem[]): GroupedSection[] {
    const sectionMap = new Map<string, RawListItem[]>();
    list.forEach(item => {
      // 如果当前section在Map中不存在,先初始化空数组
      if (!sectionMap.has(item.section)) {
        sectionMap.set(item.section, []);
      }
      // 把当前条目推入对应section的数组中
      sectionMap.get(item.section)!.push(item);
    });
    // 将Map转换为数组结构,保留section在原始数组中的出现顺序
    return Array.from(sectionMap.entries()).map(([sectionName, items]) => ({
      sectionName,
      items
    }));
  }
}
第二步:模板层通过双层*ngFor渲染

外层循环遍历每个section分组,渲染对应的区块标题;内层循环遍历当前分组下的所有条目,渲染具体内容。参考模板代码:

<!-- 外层循环:遍历所有section区块 -->
<div class="section-block" *ngFor="let section of groupedSections">
  <!-- 渲染当前区块的标题 -->
  <h3 class="section-header">{{ section.sectionName }}</h3>
  <!-- 内层循环:渲染当前区块下的所有条目 -->
  <div class="section-item" *ngFor="let item of section.items">
    第{{ item.number }}条内容
  </div>
</div>
开发避坑提示
  • 不要在模板中通过*ngIf比对“当前条目section和上一个条目section是否一致”的方式做区块切换,这种写法零散易出错,一旦数据顺序变动就会出现渲染错乱,维护成本极高。
  • 分组时优先使用Map作为映射容器,不要用普通JS对象做分组:Map会严格保留元素插入的顺序,能保证区块展示顺序和原始数组中section的出现顺序完全一致,不会出现区块顺序颠倒的问题。
  • 如果数据是异步从接口获取的,只需要在接口返回数据后重新调用groupItemsBySection方法更新groupedSections的值,模板会自动完成更新,无需额外操作。

内容的提问来源于stack exchange,提问作者Swatantra Mukherjee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 00:45:03