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构造函数参数规则是:
- 第一个参数:控件初始值
- 第二个参数:同步验证器数组(单个验证器也可以直接传,多个必须放数组)
- 第三个参数:异步验证器数组(必须返回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
相关产品推荐
相关产品推荐

