Angular基于ngModel事件实现起止日期校验的解决方案
Angular 模板驱动表单起止日期校验实现
现有代码问题
chngDt方法仅做了简单的值比较,没有给表单控件设置错误状态,validation-messages组件无法感知校验失败,无法展示提示- 直接比较日期变量未做格式统一,容易出现字符串、Date对象格式不匹配导致的判断错误
- 开始日期修改时没有同步触发结束日期的重校验,会出现先填结束日期、再改小开始日期时无提示的漏洞
- 结束日期输入框后未挂载
validation-messages组件,缺少提示渲染载体
实现代码
组件类(TS)代码
import { Component } from '@angular/core'; import { NgModel } from '@angular/forms'; @Component({ // 你的组件配置 }) export class YourBizComponent { test = { bidProgramStartDate: '', bidProgrammeEndDate: '' }; /** * 日期范围校验 * @param startDateCtrl 开始日期ngModel实例 * @param endDateCtrl 结束日期ngModel实例 */ chngDt(startDateCtrl: NgModel, endDateCtrl: NgModel) { // 两个日期都填写时才做范围校验 if (this.test.bidProgramStartDate && this.test.bidProgrammeEndDate) { // 统一转时间戳对比,避免格式/时区问题 const startTs = new Date(this.test.bidProgramStartDate).getTime(); const endTs = new Date(this.test.bidProgrammeEndDate).getTime(); if (startTs > endTs) { // 给结束日期控件追加范围错误标记 endDateCtrl.control.setErrors({ ...endDateCtrl.control.errors, dateRangeInvalid: true }); return; } } // 校验通过,移除自定义范围错误 if (endDateCtrl.control.hasError('dateRangeInvalid')) { const restErrors = { ...endDateCtrl.control.errors }; delete restErrors.dateRangeInvalid; endDateCtrl.control.setErrors(Object.keys(restErrors).length ? restErrors : null); } } }
模板(HTML)代码
<div class="my-3"> <label class="form-label" for="Test_BidProgramStartDate"> {{ l('BidProgramStartDate') }} * </label> <input type="date" #Test_BidProgramStartDate="ngModel" id="Test_BidProgramStartDate" class="form-control" [(ngModel)]="test.bidProgramStartDate" name="BidProgramStartDate" required (change)="chngDt(Test_BidProgramStartDate, Test_BidProgrammeEndDate)" /> <validation-messages [formCtrl]="Test_BidProgramStartDate"></validation-messages> </div> <div class="my-3"> <label class="form-label" for="Test_BidProgrammeEndDate"> {{ l('BidProgrammeEndDate') }} * </label> <input type="date" #Test_BidProgrammeEndDate="ngModel" id="Test_BidProgrammeEndDate" class="form-control" [(ngModel)]="test.bidProgrammeEndDate" name="BidProgrammeEndDate" required (change)="chngDt(Test_BidProgramStartDate, Test_BidProgrammeEndDate)" /> <validation-messages [formCtrl]="Test_BidProgrammeEndDate"> <!-- 范围错误提示 --> <div *ngIf="Test_BidProgrammeEndDate.hasError('dateRangeInvalid')" class="text-danger mt-1"> * 结束日期必须大于开始日期 </div> </validation-messages> </div>
关键说明
- 所有日期对比统一转成毫秒时间戳后再比较,彻底规避字符串格式、时区差异导致的判断偏差
- 开始、结束日期的变更事件都绑定同一个校验方法,任意一个日期修改都会触发重校验
- 操作控件错误时保留原有必填等其他错误标记,不会覆盖框架原生的校验状态
- 校验通过时主动移除自定义错误标记,避免控件长期处于错误状态
内容的提问来源于stack exchange,提问作者ravindra
相关产品推荐
相关产品推荐

