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
相关产品推荐
相关产品推荐

