You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular自定义Formly日期选择组件失焦不显示验证消息问题

问题原因

你的自定义日期选择器未监听输入框的blur事件,也没有在输入框失去焦点时调用ControlValueAccessor的_onTouch方法,导致父表单控件始终处于untouched状态,验证规则无法触发错误消息显示。

同时,当前代码仅处理了keyup事件(输入框手动输入)的逻辑,未正确处理dateSelect事件(选择日历日期)的参数类型,会导致选择日期时无法同步值和标记触摸状态。

解决方案

1. 为输入框添加blur事件监听

修改自定义日期选择器的模板,给input标签增加(blur)事件绑定:

<input
  class="form-control"
  placeholder="yyyy-mm-dd"
  name="dp"
  [formControl]="myControl"
  ngbDatepicker
  #d="ngbDatepicker"
  (keyup)="change($event)"
  (dateSelect)="change($event)"
  (blur)="onBlur()" <!-- 新增blur事件监听 -->
/>

2. 实现onBlur方法标记控件为已触摸

在NgbdDatepickerPopup类中添加onBlur方法,调用_onTouch来通知父控件标记为touched:

onBlur() {
  this._onTouch();
}

3. 修正change方法的逻辑(处理两种事件类型)

dateSelect事件的参数是NgbDate对象而非Event,需要补充处理这种情况,同时统一_onTouch的调用方式(不需要传参):

change(event: unknown) {
  let date = '';
  if (event instanceof Event) {
    // 处理手动输入的情况
    date = (event.target as HTMLInputElement).value;
  } else {
    // 处理日历选择的情况,转换为yyyy-mm-dd格式
    const ngbDate = event as { year: number; month: number; day: number };
    date = `${ngbDate.year}-${ngbDate.month.toString().padStart(2, '0')}-${ngbDate.day.toString().padStart(2, '0')}`;
  }
  
  this._onChange(date);
  this._onTouch(); // 统一调用,标记控件为已触摸
}
效果验证

修改完成后,当用户点击输入框再点击外部时,blur事件会触发onBlur方法,父表单控件会被标记为touched;同时选择日历日期时也能正确同步值和触摸状态,验证不通过时Formly的错误消息会正常显示。

内容的提问来源于stack exchange,提问作者Emz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:47:56