如何用Angular Material实现仅选年月的MM/YYYY格式日期范围选择器
Angular Material 实现MM/YYYY格式年月范围选择器
基于你已完成的单年月选择器逻辑,改造为范围选择器只需替换日期范围组件、调整表单结构和选中回调即可,完整实现如下:
1. TS 逻辑调整
将单个表单控件替换为表单组管理起止日期,新增选择阶段标记区分当前选中的是开始月还是结束月,补充日期大小校验避免结束日期早于开始日期:
import {Component} from '@angular/core'; import {FormGroup, FormControl} from '@angular/forms'; import {MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from '@angular/material-moment-adapter'; import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core'; import {MatDateRangePicker} from '@angular/material/datepicker'; import * as _moment from 'moment'; import {default as _rollupMoment, Moment} from 'moment'; const moment = _rollupMoment || _moment; // 自定义年月显示格式,与单日期选择器配置保持一致 export const MY_FORMATS = { parse: { dateInput: 'MM/YYYY', }, display: { dateInput: 'MM/YYYY', monthYearLabel: 'MMM YYYY', dateA11yLabel: 'LL', monthYearA11yLabel: 'MMMM YYYY', }, }; @Component({ selector: 'month-range-picker-example', templateUrl: 'month-range-picker-example.html', styleUrls: ['month-range-picker-example.css'], providers: [ { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS], }, {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS}, ], }) export class MonthRangePickerExample { // 表单组管理起止日期 dateRange = new FormGroup({ start: new FormControl(moment()), end: new FormControl(moment().add(1, 'month')) }); // 标记当前选择阶段:选择开始月/选择结束月 private currentSelectPhase: 'start' | 'end' = 'start'; setMonthAndYear(selectedMonth: Moment, datepicker: MatDateRangePicker<Moment>) { const targetDate = moment(selectedMonth); if (this.currentSelectPhase === 'start') { // 赋值开始月,自动切换到结束月选择阶段 this.dateRange.patchValue({start: targetDate}); this.currentSelectPhase = 'end'; } else { // 校验结束月与开始月的大小关系 if (targetDate.isBefore(this.dateRange.value.start)) { // 结束月早于开始月时自动交换两个值 this.dateRange.patchValue({ start: targetDate, end: this.dateRange.value.start }); } else { this.dateRange.patchValue({end: targetDate}); } // 选完结束月后重置阶段,关闭选择面板 this.currentSelectPhase = 'start'; datepicker.close(); } } }
2. HTML 模板调整
将原单日期输入替换为mat-date-range-input范围输入组件,绑定表单组和起止控件,保留原有的多年起始视图、月份选中事件配置:
<mat-form-field appearance="fill"> <mat-label>年月范围</mat-label> <mat-date-range-input [rangePicker]="dp" [formGroup]="dateRange"> <input matStartDate formControlName="start" placeholder="开始月份"> <input matEndDate formControlName="end" placeholder="结束月份"> </mat-date-range-input> <mat-hint>MM/YYYY – MM/YYYY</mat-hint> <mat-datepicker-toggle matSuffix [for]="dp"></mat-datepicker-toggle> <mat-date-range-picker #dp startView="multi-year" (monthSelected)="setMonthAndYear($event, dp)" panelClass="month-range-picker-panel"> </mat-date-range-picker> </mat-form-field>
3. 可选样式优化
如果需要屏蔽日期面板的日级选择能力,避免用户误操作,可以添加如下样式隐藏日单元格的点击响应:
.month-range-picker-panel .mat-calendar-period-button, .month-range-picker-panel .mat-calendar-arrow { display: none; } .month-range-picker-panel .mat-calendar-body-cell { pointer-events: none; }
实现说明:选中的年月范围可直接通过
this.dateRange.value获取,返回的start和end均为Moment实例,可直接调用Moment API做后续的格式化、时长计算等处理。如果需要默认打开面板直接进入月选择层级,保留startView="multi-year"配置即可。
内容的提问来源于stack exchange,提问作者Irakli925
相关产品推荐
相关产品推荐

