如何以编程方式触发bsDatepicker输入组件的验证
针对ngx-bootstrap 2.0.2版本bsDatepicker手动触发校验的可行方案
以下方案完全兼容Angular 4.4.6 + ngx-bootstrap 2.0.2的版本约束,不需要升级依赖:
- 核心实现:通过Angular表单原生API触发控件校验,不依赖bsDatepicker内部未暴露的方法,稳定性最高
- 首先给包裹两个日期输入的表单标签添加模板引用:
<form #projectForm="ngForm"> <!-- 原有两个日期输入组件代码无需修改,直接放在表单标签内即可 --> </form>- 在组件类中获取表单实例:
import { ViewChild } from '@angular/core'; import { NgForm } from '@angular/forms'; // 组件类内部声明 @ViewChild('projectForm') projectForm: NgForm;- 在需要触发校验的事件逻辑(比如表单提交、外部按钮点击、其他业务回调)中,直接调用表单控件的原生校验方法:
// 触发开始日期控件校验 const startControl = this.projectForm.form.get('dateStart'); startControl.markAsTouched(); // 确保控件错误状态能正常渲染到视图 startControl.updateValueAndValidity(); // 重新执行所有绑定的校验规则(required、minDate等) // 触发结束日期控件校验 const endControl = this.projectForm.form.get('dateEnd'); endControl.markAsTouched(); endControl.updateValueAndValidity(); - 交互优化:联动触发关联控件校验
由于两个日期的minDate规则互相关联,可以直接在已绑定的reset回调中加入关联控件的校验触发逻辑,从根源上避免日期修改后关联控件校验不更新的问题:- 调整模板中
ngModelChange的传参,标识当前修改的字段:
<!-- 开始日期输入的ngModelChange调整 --> (ngModelChange)="reset($event, 'start')" <!-- 结束日期输入的ngModelChange调整 --> (ngModelChange)="reset($event, 'end')"- 在reset方法中加入联动校验逻辑:
reset(changedValue: Date, fieldType: 'start' | 'end') { // 保留原有重置逻辑 const relatedControl = fieldType === 'start' ? this.projectForm.form.get('dateEnd') : this.projectForm.form.get('dateStart'); // 传入emitEvent:false避免触发递归的ngModelChange回调 relatedControl.updateValueAndValidity({emitEvent: false}); relatedControl.markAsTouched(); } - 调整模板中
- 兜底方案:自定义校验器绕过组件内置bug
如果上述方案仍受bsDatepicker内置校验bug影响,可以直接弃用组件自带的[minDate]绑定,自行实现校验规则,完全脱离组件内部逻辑的限制:
在组件初始化阶段将上述校验器绑定到对应表单控件上即可,后续调用import { ValidatorFn, AbstractControl } from '@angular/forms'; // 开始日期校验:不能晚于结束日期 const startDateValidator = (getEndDate: () => Date): ValidatorFn => { return (control: AbstractControl) => { const startVal = control.value; const endVal = getEndDate(); if (!startVal || !endVal) return null; return startVal.getTime() > endVal.getTime() ? {minDate: true} : null; } } // 结束日期校验:不能早于开始日期 const endDateValidator = (getStartDate: () => Date): ValidatorFn => { return (control: AbstractControl) => { const endVal = control.value; const startVal = getStartDate(); if (!endVal || !startVal) return null; return endVal.getTime() < startVal.getTime() ? {minDate: true} : null; } }updateValueAndValidity时会直接执行自定义校验逻辑,完全不受组件版本bug影响。
- 注意:不要尝试调用bsDatepicker模板实例的内部私有方法,2.0.2版本没有暴露稳定的手动校验API,依赖私有属性实现的逻辑兼容性极差,使用Angular表单原生API是旧版本下最稳妥的实现方式。
内容的提问来源于stack exchange,提问作者javaistaucheineinsel
相关产品推荐
相关产品推荐

