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

Angular 5自定义验证报错:Expected validator to return Promise or Observable

Angular 5自定义表单验证报错:Expected validator to return Promise or Observable的解决方法

问题描述

我在Angular 5中尝试实现自定义表单验证时,遇到了如下报错:

Expected validator to return Promise or Observable

我希望当输入值不符合要求时,给表单返回错误信息,以下是我的代码:

表单所在组件代码

constructor(fb: FormBuilder, private cadastroService:CadastroService) { 
  this.signUp = fb.group({ 
    "name": ["", Validators.compose([Validators.required, Validators.minLength(2)])], 
    "email": ["", Validators.compose([Validators.required, Validators.email])], 
    "phone": ["", Validators.compose([Validators.required, Validators.minLength(5)])], 
    "cpf": ["", Validators.required, ValidateCpf] 
  }) 
}

自定义验证函数代码

import { AbstractControl } from '@angular/forms'; 

export function ValidateCpf(control: AbstractControl){ 
  if (control.value == 13445) { 
    return {errorCpf: true} 
  } 
  return null; 
}

请问这类自定义验证必须使用Promise或Observable吗?能否不借助它们实现?


解决方案

首先明确说:同步自定义验证完全不需要Promise或Observable,你遇到这个报错纯粹是因为表单控件的验证器参数格式写错了!

报错原因分析

看你代码里的cpf控件配置:

"cpf": ["", Validators.required, ValidateCpf]

Angular的FormControl构造函数参数规则是:

  1. 第一个参数:控件初始值
  2. 第二个参数:同步验证器数组(单个验证器也可以直接传,多个必须放数组)
  3. 第三个参数:异步验证器数组(必须返回Promise/Observable)

你现在把Validators.required和ValidateCpf分开成了第二个和第三个参数,Angular会把第三个参数的ValidateCpf当成异步验证器,但你的函数是同步的,没有返回Promise/Observable,所以就抛出了那个错误。

修正后的代码

只需要把cpf的两个同步验证器放到同一个数组里即可,有两种写法:

写法1:用Validators.compose包裹(兼容旧版本Angular)

constructor(fb: FormBuilder, private cadastroService:CadastroService) { 
  this.signUp = fb.group({ 
    "name": ["", Validators.compose([Validators.required, Validators.minLength(2)])], 
    "email": ["", Validators.compose([Validators.required, Validators.email])], 
    "phone": ["", Validators.compose([Validators.required, Validators.minLength(5)])], 
    "cpf": ["", Validators.compose([Validators.required, ValidateCpf])]
  }) 
}

写法2:直接传入数组(Angular 4+推荐写法)

constructor(fb: FormBuilder, private cadastroService:CadastroService) { 
  this.signUp = fb.group({ 
    "name": ["", [Validators.required, Validators.minLength(2)]], 
    "email": ["", [Validators.required, Validators.email]], 
    "phone": ["", [Validators.required, Validators.minLength(5)]], 
    "cpf": ["", [Validators.required, ValidateCpf]]
  }) 
}

你的ValidateCpf函数本身完全没问题,它是标准的同步验证器写法:验证不通过时返回包含错误标识的对象,验证通过时返回null,不需要做任何修改。

验证器类型总结

  • 同步验证器:返回{[key: string]: any}(验证失败)或null(验证成功),放在FormControl的第二个参数位置
  • 异步验证器:必须返回Promise<ValidationErrors | null>或Observable<ValidationErrors | null>,放在FormControl的第三个参数位置

内容的提问来源于stack exchange,提问作者Renê Silva Lima

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:04:38