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

Angular 6中如何实现支持多日期选择的datepicker组件

Angular 6 多日期选择Datepicker实现方案

Angular 6 版本的 Material Datepicker 未提供 Angular 7+ 才支持的dateClass输入属性,无法直接复用高版本基于dateClass的多选实现,可通过自定义日历单元格+接管选择事件的方式实现同等效果,无需升级框架版本。

核心实现逻辑

绕过高版本专属的dateClass接口,直接接管三个核心环节:选中日期的存储、日历单元格的自定义渲染、选中状态的切换逻辑。

分步实现

  • 存储选中日期
    在组件中用Set结构存储选中日期,天然去重,同时编写日期匹配方法,对比时统一抹平时分秒差异,仅校验年月日:

    import { Component, ChangeDetectorRef } from '@angular/core';
    import { MatDatepickerInputEvent } from '@angular/material/datepicker';
    
    @Component({
      selector: 'app-multi-date-picker',
      templateUrl: './multi-date-picker.component.html',
      styleUrls: ['./multi-date-picker.component.css']
    })
    export class MultiDatePickerComponent {
      selectedDates = new Set<Date>();
    
      constructor(private cdr: ChangeDetectorRef) {}
    
      isDateSelected(date: Date): boolean {
        const targetStamp = new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
        return Array.from(this.selectedDates).some(item => {
          const itemStamp = new Date(item.getFullYear(), item.getMonth(), item.getDate()).getTime();
          return itemStamp === targetStamp;
        });
      }
    }
    
  • 自定义日历单元格渲染
    Angular 6 支持通过*matDatepickerCalendarCell结构指令自定义每个日历单元格的内容和样式,给选中状态的日期加高亮类即可替代dateClass的样式标记能力:

    <mat-form-field appearance="fill">
      <input 
        matInput 
        [matDatepicker]="multiPicker" 
        placeholder="选择多个日期"
        (dateChange)="handleDateSelect($event)"
      >
      <mat-datepicker-toggle matSuffix [for]="multiPicker"></mat-datepicker-toggle>
      <mat-datepicker #multiPicker>
        <!-- 自定义日历单元格 -->
        <mat-calendar-cell *matDatepickerCalendarCell="let currentDate">
          <div class="date-cell" [class.is-selected]="isDateSelected(currentDate)">
            {{currentDate.getDate()}}
          </div>
        </mat-calendar-cell>
      </mat-datepicker>
    </mat-form-field>
    

    配套单元格样式:

    .date-cell {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      cursor: pointer;
    }
    .date-cell.is-selected {
      background: #1976d2;
      color: #fff;
    }
    
  • 接管日期选择逻辑
    监听输入框的dateChange事件,拦截默认的单选赋值逻辑,点击日期时切换选中状态,同时手动触发变更检测刷新日历样式:

    handleDateSelect(event: MatDatepickerInputEvent<Date>) {
      if (!event.value) return;
      // 统一抹平时间部分
      const clickedDate = new Date(
        event.value.getFullYear(),
        event.value.getMonth(),
        event.value.getDate()
      );
    
      // 切换选中状态:已选则移除,未选则加入集合
      if (this.isDateSelected(clickedDate)) {
        this.selectedDates.delete(clickedDate);
      } else {
        this.selectedDates.add(clickedDate);
      }
    
      // 清空输入框默认单选值,避免显示单个日期
      event.target.value = null;
      // 手动触发变更检测,强制日历重绘更新选中样式
      this.cdr.markForCheck();
    }
    
    // 对外提供获取选中结果的方法
    getSelectedDates(): Date[] {
      return Array.from(this.selectedDates);
    }
    

兼容注意点

  • 如果项目使用MomentDateAdapter替代原生Date适配器,日期对比逻辑可直接调用Moment的isSame(day)方法,无需手动拼接时间戳
  • 不要修改Datepicker的内部私有属性/方法,避免小版本升级出现兼容问题
  • 若需要支持范围选择,可在现有选中逻辑基础上增加起止点标记,无需改动单元格渲染逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 11:31:11