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

如何在Angular中按日期年份分组并展示事件

在Angular中实现事件按年份分组展示

1. 统一数据结构与接口

首先你的Event接口字段和后端返回的JSON字段不匹配,先修正接口确保数据一致性:

export interface Event {
  id: string;
  title: string;
  start_date: Date;
  end_date: Date;
  location?: string;
  link?: string;
}

2. 完善分组逻辑

补全并优化groupByYear相关逻辑,处理日期转换、分组排序,返回可直接用于模板的Observable:

import { Observable, reduce, map } from 'rxjs';

filteredEvents!: Observable<Event[]>;
// 存储分组后的事件:键为年份字符串,值为对应年份的事件数组
groupedEvents$!: Observable<{ [year: string]: Event[] }>;

ngOnInit() {
  // 基于已获取的filteredEvents进行分组
  this.groupedEvents$ = this.filteredEvents.pipe(
    reduce((acc, event) => {
      // 将后端返回的日期字符串转为Date对象
      const processedEvent = {
        ...event,
        start_date: new Date(event.start_date),
        end_date: new Date(event.end_date)
      };
      // 提取开始日期的年份作为分组键
      const year = processedEvent.start_date.getFullYear().toString();
      // 初始化年份数组并推入事件
      acc[year] = acc[year] || [];
      acc[year].push(processedEvent);
      return acc;
    }, {} as { [year: string]: Event[] }),
    // 对年份进行降序排序,让最新年份的事件优先展示
    map(grouped => {
      const sortedYears = Object.keys(grouped).sort((a, b) => parseInt(b) - parseInt(a));
      return sortedYears.reduce((acc, year) => {
        acc[year] = grouped[year];
        return acc;
      }, {} as { [year: string]: Event[] });
    })
  );
}

3. 模板实现分组展示

在组件HTML中使用async管道订阅分组数据,按年份渲染事件列表:

<div class="event-wrapper">
  <ng-container *ngIf="groupedEvents$ | async as groupedEvents">
    <!-- 遍历每个年份分组 -->
    <div *ngFor="let year of Object.keys(groupedEvents)" class="year-section">
      <!-- 年份标题 -->
      <h2 class="year-title">{{ year }}</h2>
      <!-- 该年份下的事件卡片列表 -->
      <div class="event-list">
        <div *ngFor="let event of groupedEvents[year]" class="event-card">
          <h3>{{ event.title }}</h3>
          <p>
            时间:{{ event.start_date | date:'yyyy-MM-dd HH:mm' }} 
            至 {{ event.end_date | date:'yyyy-MM-dd HH:mm' }}
          </p>
          <p *ngIf="event.location">地点:{{ event.location }}</p>
          <a *ngIf="event.link" [href]="event.link" target="_blank">查看详情</a>
        </div>
      </div>
    </div>
  </ng-container>
</div>

4. 基础样式适配

添加CSS样式让分组展示更贴合预期UI:

.event-wrapper {
  max-width: 1200px;
  margin: 2rem auto;
  padding: 0 1rem;
}

.year-section {
  margin-bottom: 2rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid #e0e0e0;
}

.year-title {
  color: #2d3748;
  font-size: 1.8rem;
  margin-bottom: 1rem;
}

.event-card {
  background-color: #f7fafc;
  padding: 1rem;
  border-radius: 8px;
  margin-bottom: 1rem;
}

.event-card h3 {
  margin-top: 0;
  color: #1a202c;
}

.event-card p {
  margin: 0.5rem 0;
  color: #4a5568;
}

可选扩展

如果需要将跨年份的事件(开始和结束年份不同)同时分到两个年份组中,可修改分组逻辑:

// 替换reduce中的处理逻辑
const startYear = processedEvent.start_date.getFullYear().toString();
const endYear = processedEvent.end_date.getFullYear().toString();

// 推入开始年份组
acc[startYear] = acc[startYear] || [];
acc[startYear].push(processedEvent);

// 若结束年份不同,同时推入结束年份组
if (startYear !== endYear) {
  acc[endYear] = acc[endYear] || [];
  acc[endYear].push(processedEvent);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 15:57:46