Angular Material Datepicker先选月后选年无日选择实现优化问询
Angular Material Datepicker 月年选择实现优化方案
现有实现可优化点
你的现有实现存在几个可以改进的点:
- 硬编码250ms延迟重启弹窗,依赖设备渲染速度,不同场景下可能出现弹窗打不开、闪烁的问题
- 同时维护FormControl和独立的
_startDate变量,两份状态容易出现数据不一致 - 额外维护
isMonthOpened状态控制起始视图,逻辑冗余 - 表单区域绑定click事件重复触发打开逻辑,可能和自带的toggle行为冲突
优化后实现代码
example.component.ts
import { FormControl } from '@angular/forms'; import { MatDatepicker } from '@angular/material/datepicker'; import * as moment from 'moment'; public chosenMonthHandler(normalizedMonth: moment.Moment, datepicker: MatDatepicker<moment.Moment>, dateFormControl: FormControl): void { // 兼容表单无初始值的场景 const currentVal = dateFormControl.value || moment(); currentVal.month(normalizedMonth.month()); dateFormControl.setValue(currentVal); // 直接切换到多年选择视图,无需关闭重开 datepicker.goToMultiYearView(); } public chosenYearHandler(normalizedYear: moment.Moment, datepicker: MatDatepicker<moment.Moment>, dateFormControl: FormControl): void { const currentVal = dateFormControl.value || moment(); currentVal.year(normalizedYear.year()); dateFormControl.setValue(currentVal); // 年份选择完成直接关闭弹窗 datepicker.close(); }
example.component.html
<mat-form-field appearance="outline" class="custom-form-field"> <mat-label>Start</mat-label> <input matInput [matDatepicker]="startDP" [formControl]="startDateFormControl" /> <mat-datepicker-toggle matSuffix [for]="startDP"></mat-datepicker-toggle> <mat-datepicker #startDP startView="year" (yearSelected)="chosenYearHandler($event, startDP, startDateFormControl)" (monthSelected)="chosenMonthHandler($event, startDP, startDateFormControl)" > </mat-datepicker> </mat-form-field>
优化优势
- 采用Angular Material官方提供的视图切换API,无硬编码延迟,不会出现弹窗异常问题
- 所有日期状态统一由FormControl管理,移除冗余状态变量,避免多源数据不一致
- 移除冗余的点击事件绑定,完全复用组件原生交互逻辑,降低冲突概率
- 代码量更精简,可维护性更高
内容的提问来源于stack exchange,提问作者Nicolas Bodin
相关产品推荐
相关产品推荐

