Angular模板如何按月份对事件行分组并避免重复显示月份
方案1:组件层预分组(推荐)
该方案逻辑清晰、性能稳定,也是Angular官方推荐的列表分组实现方式。
- 首先在对应模块的
providers中添加DatePipe依赖 - 组件TS代码:
import { DatePipe } from '@angular/common'; // 组件类内部代码 groupedEvents: { monthLabel: string, events: any[] }[] = []; constructor(private datePipe: DatePipe) {} ngOnInit() { // 可选:先对事件按开始时间排序,保证时间顺序正确 const sortedEvents = this.events.sort((a, b) => new Date(a.start_date).getTime() - new Date(b.start_date).getTime() ); const groupMap = new Map<string, { monthLabel: string, events: any[] }>(); sortedEvents.forEach(event => { // 用年月作为分组唯一key,避免不同年同月份合并 const monthKey = this.datePipe.transform(event.start_date, 'yyyy-MM')!; if (!groupMap.has(monthKey)) { groupMap.set(monthKey, { monthLabel: this.datePipe.transform(event.start_date, 'MMMM yyyy')!, events: [] }); } groupMap.get(monthKey)?.events.push(event); }); // 把Map转为数组供模板遍历 this.groupedEvents = Array.from(groupMap.values()); }
- 模板代码:
<div *ngFor="let group of groupedEvents"> <div class="month-row">{{ group.monthLabel }}</div> <div *ngFor="let event of group.events" class="name">{{ event.name }}</div> </div>
方案2:模板内直接判断(适合小数据量场景)
如果不想修改TS逻辑,且事件列表已经提前按时间排序,可以直接在模板内通过索引对比月份实现去重:
<div *ngFor="let event of events; let i = index"> <div class="month-row" *ngIf="i === 0 || (event.start_date | date: 'yyyy-MM') !== (events[i-1].start_date | date: 'yyyy-MM')" > {{ event.start_date | date: 'MMMM yyyy' }} </div> <div class="name">{{ event.name }}</div> </div>
该方案缺点是数据量大时会有性能损耗,且必须保证事件列表已经按时间排序,否则会出现同月份重复显示标题的问题。
内容的提问来源于stack exchange,提问作者A. Nurb
相关产品推荐
相关产品推荐

