Angular 13里程碑展示优化:如何让同一年份的月份仅显示一次?
解决方案
要实现同一年份下月份名称仅显示一次、下方罗列对应详情的效果,需要调整数据格式化逻辑和HTML模板结构:
1. 修改TS数据格式化代码
当前的reduce仅按年份分组,未对月份做聚合,需要在年份分组内再按月份名称聚合详情:
this.formattedMileStoneData = this.allMileStones.reduce((a: any, b: any) => { // 查找当前年份对应的分组 const yearGroup = a.find((x: any) => x.Year === b.Year); if (yearGroup) { // 查找当前月份对应的分组 const monthGroup = yearGroup.Month.find((m: any) => m.MonthName === b.MonthName); if (monthGroup) { // 已有该月份分组,添加详情 monthGroup.Details.push(b.Details); } else { // 无该月份分组,新建并初始化详情数组 yearGroup.Month.push({ MonthName: b.MonthName, Details: [b.Details] }); } } else { // 无当前年份分组,新建年份及对应月份分组 a.push({ Year: b.Year, Month: [{ MonthName: b.MonthName, Details: [b.Details] }] }); } return a; }, []);
2. 调整HTML模板结构
修改循环层级,先显示年份,再循环月份分组(每个月份仅显示一次名称),最后循环该月份下的所有详情:
<section class="milestone-wrapper"> <section class="milestone-wrap-info"> <ul class="timeline"> <li *ngFor="let milestone of formattedMileStoneData"> <div class="direction-r"> <div class="flag-wrapper"> <span class="flag">{{milestone.Year}}</span> </div> <!-- 循环每个月份分组 --> <div class="desc" *ngFor="let monthGroup of milestone.Month"> <!-- 仅显示一次月份名称 --> <label>{{monthGroup.MonthName}}</label> <!-- 循环显示该月份下的所有详情 --> <p *ngFor="let detail of monthGroup.Details">{{detail}}</p> </div> </div> </li> </ul> </section> </section>
可选:添加排序逻辑(按需)
如果需要按时间顺序或指定顺序展示年份、月份,可以在格式化后添加排序:
// 对年份降序排序(可改为升序) this.formattedMileStoneData.sort((x, y) => parseInt(y.Year) - parseInt(x.Year)); // 对每个年份下的月份按原数据的DisplayOrder排序 this.formattedMileStoneData.forEach(yearGroup => { yearGroup.Month.sort((m1, m2) => { const m1Order = this.allMileStones.find(item => item.Year === yearGroup.Year && item.MonthName === m1.MonthName)?.DisplayOrder || '0'; const m2Order = this.allMileStones.find(item => item.Year === yearGroup.Year && item.MonthName === m2.MonthName)?.DisplayOrder || '0'; return parseInt(m1Order) - parseInt(m2Order); }); });
内容的提问来源于stack exchange,提问作者Rishf P
相关产品推荐
相关产品推荐

