matDatepicker使用matDatepickerFilter输入无效日期后日历全部禁用问题
问题根因
你的matDatepickerFilter校验函数逻辑存在错误:matDatepickerFilter的入参date是日历组件渲染的每个待选日期,你现有代码完全没有用到这个入参,反而用了当前表单里填写的formatedEndDate做判断。当你手动输入的endDate早于startDate时,判断语句new Date(this.formatedStartDate) <= new Date((this.formatedEndDate))会返回false,导致所有待选日期都被过滤禁用。
同时minDate的赋值放在过滤器里执行也不合理,过滤器会在日历渲染时高频触发,不需要在这里重复赋值。
修复方案
1. 最简修复(推荐)
Angular Material日期选择器自带的min属性已经可以实现「禁用早于startDate的日期」的效果,和你加的matDatepickerFilter功能完全重叠,直接删除过滤器绑定即可:
<!-- 修正后的html代码,删除matDatepickerFilter绑定 --> <input matInput #ref [matDatepicker]="this.enddate" [min]="minDate" formControlName="commissionProgramEndDt" id="commprogram.commissionProgramEndDt" required>
// 把minDate的赋值移到startDate变更的时机执行即可,比如startDate的valueChanges订阅、表单初始化阶段 this.minDate = new Date(this.formatedStartDate);
2. 保留过滤器的修复方案
如果你有其他复杂过滤逻辑需要保留matDatepickerFilter,修正校验函数逻辑即可:
// minDate赋值和上面一致,移到过滤器外执行 this.minDate = new Date(this.formatedStartDate); endDateValidator: (date: Date | null) => boolean = (date: Date | null) => { if (!date) return true; // 用过滤器传入的待选日期和minDate对比,和当前表单填写的错误endDate无关 return date >= this.minDate; }
手动输入校验补充
如果需要保留手动输入时的「endDate >= startDate」校验,给表单控件加独立的自定义校验器即可,不要和日期选择器的过滤逻辑混用:
// 表单初始化时添加校验规则 this.yourForm = this.fb.group({ // 其他表单控件... commissionProgramEndDt: [null, [Validators.required, this.endDateInputValidator.bind(this)]] }) // 独立的输入校验器 endDateInputValidator(control: AbstractControl) { const endDate = control.value; if (!endDate || !this.minDate) return null; return new Date(endDate) >= this.minDate ? null : { endDateInvalid: true }; }
调整后日期选择器的可选范围仅和startDate挂钩,无论之前输入的endDate是否符合规则,打开日历都可以正常选择大于等于startDate的日期,手动输入的校验逻辑独立触发,互不干扰。
内容的提问来源于stack exchange,提问作者techDoubts23
相关产品推荐
相关产品推荐

