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,提问作者Тарас Мацюк
相关产品推荐
相关产品推荐

