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

如何在angular-calendar中按元数据固定周视图用户事件列位置?

Angular Calendar周视图按用户固定列展示事件实现方案

完全可以实现,核心思路是自定义周视图模板+用户列固定配置,以下是具体步骤:

1. 定义固定的用户列配置

先提前配置好每个用户对应的列位置、颜色,数组的顺序直接决定列的左右排列顺序:

// 组件内定义用户列配置,固定顺序对应列的左右位置
userColumnConfigs = [
  { userId: 'user1', columnIndex: 0, color: '#ffb3ba' }, // 粉色列(最左侧)
  { userId: 'user2', columnIndex: 1, color: '#ff6b6b' }, // 红色列(中间)
  { userId: 'user3', columnIndex: 2, color: '#86e49d' }  // 绿色列(最右侧)
];

2. 给事件关联用户ID

确保每个事件的meta字段携带对应用户ID,用来匹配到对应的列和颜色:

events: CalendarEvent[] = [
  {
    start: new Date(),
    end: new Date(new Date().setHours(new Date().getHours() + 2)),
    title: '用户1的项目评审会',
    meta: { userId: 'user1' } // 绑定用户标识
  },
  {
    start: new Date(new Date().setHours(14)),
    end: new Date(new Date().setHours(16)),
    title: '用户2的客户对接',
    meta: { userId: 'user2' }
  },
  // 更多事件...
];

3. 自定义周视图模板

重写angular-calendar的周视图模板,将每一天的区域拆分为预先定义的用户列,把对应用户的事件渲染到固定列中:

<mwl-calendar-week-view
  [viewDate]="viewDate"
  [events]="events"
  [customTemplate]="customWeekViewTemplate"
></mwl-calendar-week-view>

<!-- 自定义周视图模板 -->
<ng-template #customWeekViewTemplate let-view="view" let-day="day" let-events="events">
  <div class="calendar-day">
    <!-- 日期头部 -->
    <div class="day-header">{{ day.date | date:'EEE, MMM d' }}</div>
    <!-- 用户列容器 -->
    <div class="user-columns">
      <div 
        *ngFor="let userConfig of userColumnConfigs"
        class="user-column"
        [style.width]="100 / userColumnConfigs.length + '%'"
      >
        <!-- 用户列头部(可选,显示用户名) -->
        <div class="column-header" [style.backgroundColor]="userConfig.color">
          {{ userConfig.userId }}
        </div>
        <!-- 渲染当前用户当天的事件 -->
        <div 
          *ngFor="let event of events.filter(e => e.meta?.userId === userConfig.userId)"
          class="calendar-event"
          [style.backgroundColor]="userConfig.color"
          [style.top]="getEventTop(event, day) + '%'"
          [style.height]="getEventHeight(event, day) + '%'"
        >
          <span class="event-title">{{ event.title }}</span>
        </div>
      </div>
    </div>
  </div>
</ng-template>

4. 实现事件位置计算方法

通过计算事件的开始时间、持续时长,确定事件在列中的垂直位置和高度:

// 计算事件顶部偏移百分比
getEventTop(event: CalendarEvent, day: CalendarDay): number {
  const dayStart = new Date(day.date);
  dayStart.setHours(0, 0, 0, 0);
  const minutesSinceDayStart = (event.start.getTime() - dayStart.getTime()) / (1000 * 60);
  return (minutesSinceDayStart / (24 * 60)) * 100;
}

// 计算事件高度百分比
getEventHeight(event: CalendarEvent, day: CalendarDay): number {
  const durationMinutes = (event.end.getTime() - event.start.getTime()) / (1000 * 60);
  return (durationMinutes / (24 * 60)) * 100;
}

5. 添加样式调整

通过CSS确保列布局和事件展示正常:

.calendar-day {
  position: relative;
  height: 600px; /* 自定义日历每天的高度 */
  border: 1px solid #eee;
  margin-bottom: 8px;
}

.day-header {
  padding: 8px;
  background-color: #f5f5f5;
  border-bottom: 1px solid #eee;
  font-weight: 500;
}

.user-columns {
  display: flex;
  height: calc(100% - 40px); /* 减去日期头部高度 */
}

.user-column {
  position: relative;
  border-right: 1px solid #eee;
  box-sizing: border-box;
}

.user-column:last-child {
  border-right: none;
}

.column-header {
  padding: 4px;
  color: #fff;
  font-size: 12px;
  text-align: center;
}

.calendar-event {
  position: absolute;
  left: 3px;
  right: 3px;
  padding: 4px;
  border-radius: 4px;
  color: #fff;
  font-size: 12px;
  overflow: hidden;
  cursor: pointer;
}

额外优化点

  • 如果需要处理跨天事件,可以在模板中判断事件是否跨天,拆分到对应日期的列中;
  • 若存在同用户同时间段的重叠事件,可添加重叠偏移逻辑,避免事件完全覆盖;
  • 可以通过angular-calendar的CalendarWeekViewBeforeRenderEvent钩子,提前对事件进行分组处理,减少模板中的过滤逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 17:31:06