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

Angular mat-date-range-picker能否仅在月份视图下选择日期区间

实现Angular mat-date-range-picker月份视图选整月区间方案

完全可以实现该需求,无需自定义重写组件,基于你现有代码补充逻辑即可,具体实现步骤如下:

1. 修改组件模板

你现有的模板已经配置了startView="year"和monthSelected事件,补充视图切换拦截逻辑即可,完整模板代码如下:

<mat-form-field appearance="fill">
  <mat-label>Enter a date range</mat-label>
  <mat-date-range-input
    [formGroup]="range"
    [rangePicker]="picker"
    [dateFilter]='dateFilter'
  >
    <input matStartDate placeholder="Start date" formControlName="start">
    <input matEndDate placeholder="End date" formControlName="end">
  </mat-date-range-input>
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-date-range-picker 
    (monthSelected)='monthSelectedHandler($event, picker)' 
    startView='year' 
    (opened)='clearSelectedDates()'
    (viewChanged)="onViewChanged($event, picker)"
    #picker
  ></mat-date-range-picker>
</mat-form-field>

2. 编写组件TS逻辑

import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { MatDateRangePicker } from '@angular/material/datepicker';

@Component({
  selector: 'app-date-range-picker',
  templateUrl: './date-range-picker.component.html',
  styleUrls: ['./date-range-picker.component.css']
})
export class DateRangePickerComponent {
  range: FormGroup;
  // 存储是否已经选中起始月份
  private isStartSelected = false;
  // 临时存储起始月份
  private tempStartDate: Date | null = null;

  constructor(private fb: FormBuilder) {
    this.range = this.fb.group({
      start: [null],
      end: [null]
    });
  }

  // 禁用所有天级选择,用户无法点击具体日期
  dateFilter = () => false;

  // 拦截视图切换,始终停留在年(月份选择)视图
  onViewChanged(event: any, picker: MatDateRangePicker<Date>) {
    if (event.view !== 'year') {
      picker.startView = 'year';
      picker.goToView('year');
    }
  }

  // 月份选择事件处理
  monthSelectedHandler(selectedMonth: Date, picker: MatDateRangePicker<Date>) {
    if (!this.isStartSelected) {
      // 第一次选择:存为起始月份
      this.tempStartDate = selectedMonth;
      this.isStartSelected = true;
    } else {
      // 第二次选择:补全起止日期,赋值给表单
      const start = new Date(this.tempStartDate!.getFullYear(), this.tempStartDate!.getMonth(), 1);
      // 结束日期取选中月份的最后一天
      const end = new Date(selectedMonth.getFullYear(), selectedMonth.getMonth() + 1, 0);
      this.range.patchValue({
        start: start,
        end: end
      });
      // 关闭选择器,重置状态
      picker.close();
      this.clearSelectedDates();
    }
  }

  // 打开选择器时清空状态
  clearSelectedDates() {
    this.isStartSelected = false;
    this.tempStartDate = null;
  }
}

3. 可选优化

如果需要输入框仅显示年-月格式,可在模块中配置自定义日期格式:

import { MAT_DATE_FORMATS } from '@angular/material/core';

export const MONTH_YEAR_FORMATS = {
  parse: {
    dateInput: 'YYYY-MM',
  },
  display: {
    dateInput: 'YYYY-MM',
    monthYearLabel: 'YYYY年MM月',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'YYYY年MM月',
  },
};

// 在模块的providers中添加
providers: [
  { provide: MAT_DATE_FORMATS, useValue: MONTH_YEAR_FORMATS }
]

实现效果

月份视图选日期区间效果示例

内容的提问来源于stack exchange,提问作者Тарас Мацюк

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:09:03