期望验证器返回 Promise 或 Observable

Posted

技术标签:

【中文标题】期望验证器返回 Promise 或 Observable【英文标题】:Expected validator to return Promise or Observable 【发布时间】:2018-11-05 23:12:04 【问题描述】:

我正在尝试在 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;

这种类型的验证是否仅适用于可观察对象,或者我可以在没有承诺或可观察对象的情况下进行验证吗?

【问题讨论】:

【参考方案1】:

这意味着你必须在数组中添加多个验证器

。 示例:

有错误

profileFormGroup = 
  budget: [null, Validators.required, Validators.min(1)]
;

验证器返回 Promise 或 Observable

修复:

profileFormGroup = 
  budget: [null, [Validators.required, Validators.min(1)]]
;

说明:

使用多个验证器时,通过使用内置验证器完成的角度响应式表单验证可以在第二个位置的数组中给出。

FIELD_KEY:[INITIAL_VALUE,[LIST_OF_VALIDATORS]]

【讨论】:

有趣的是,我完全错过了接受/流行答案中验证器周围的括号。您很好地指出了问题和解决方案。 你的第一点是正确的答案。这个答案应该标记为正确的。 对有角的家伙感到羞耻!这个问题根本看不到,它是数组语法 完美...第一行本身就解决了我的问题【参考方案2】:

以下应该有效:

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

表单控件期望的参数如下:

constructor(formState: any = null, 
            validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
            asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null)

来自https://angular.io/api/forms/FormControl

【讨论】:

【参考方案3】:

我认为,除了已接受的答案之外,最好澄清一下错误的发生,因为在使用反应式表单创建 FormControl 时,在 initial_value 之后,以下参数分别是同步验证器和异步验证器,以以下形式分组每个数组。例如:

myFormGroup = this.fb.group(
    myControl: ['', [ mySyncValidators ], [ myAsyncValidators ] ]
)

如果控件碰巧只有其中一个,Angular 将其作为单个元素接受。例如:

myFormGroup = this.fb.group(
    myControl: ['', mySyncValidator, myAsyncValidator ]
)

因此,当忘记分组它们的括号时,Angular 假定第二个验证器项是异步验证器的一部分,因此我们得到 Expected validator to return Promise or Observable

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:

如果你做这样的事情通常会发生这种类型的错误 -

name: ['',Validators.required, Validators.compose([Validators.minLength(3),Validators.maxLength(15)])]

把它改成 -

name: ['', Validators.compose([Validators.required,Validators.minLength(3),Validators.maxLength(15)])]

第二个字段 -> 验证器

【讨论】:

【参考方案6】:

如果您添加多个验证器,那么您需要添加另一个第三个括号“[]”,并在其中放置您的验证器。如下:

this.yourForm= this.formBuilder.group(
    amount: [null, [Validators.required, Validators.min(1)]],
);

【讨论】:

【参考方案7】:

与 OP 的问题没有直接关系,但我在稍微不同的问题上遇到了同样的错误。我有一个异步验证器,但我忘了从它返回一个 Observable(或 Promise)。

这是我原来的异步验证器

public availableEmail(formControl: FormControl) 
   if(formControl && formControl.value)
     return this.http.get('')
   

问题是,如果 if 语句为假怎么办?我们不返回任何东西,并且我们得到一个运行时错误。我添加了返回类型(如果我们没有返回正确的类型,请确保 IDE 会抱怨),然后在 if 语句失败的情况下返回 of(true)

这是更新的异步验证器。

public availableEmail(formControl: FormControl): Observable<any> 
   if(formControl && formControl.value)
     return this.http.get('someUrl');
   
   return of(true);

【讨论】:

【参考方案8】:

Validators.compose() 是多余的;

你可以只传递一个数组。 OP 的问题是由于未能将验证器包装在 [] 中以使它们成为数组,因此 minLength() 被假定为异步并产生错误消息。

我希望,这个解决方案会帮助你。谢谢。

【讨论】:

是的。我使用了 Validators.compose([])。它对我有用【参考方案9】:

错误: 用户名:['',[Validators.required,Validators.minLength(3)],forbiddenNameValidator(/password/)],

回答: 用户名:['',[Validators.required,Validators.minLength(3),forbiddenNameValidator(/password/)]],

验证器仅使用内部数组中的第二个参数。不适用于外部数组

【讨论】:

“这可能无法提供问题的答案。请添加适当的解释。一旦您有足够的声誉,您就可以对任何帖子发表评论;相反,提供不需要提问者澄清的答案。”【参考方案10】:

您肯定在响应式表单中定义了多个验证器。

错了:

'status': [false,,[Validators.required]]

我只是在定义status false的值后使用了两个逗号(,)

正确:

 'status': [false,[Validators.required]]

【讨论】:

以上是关于期望验证器返回 Promise 或 Observable的主要内容,如果未能解决你的问题,请参考以下文章

函数返回未定义,预期Promise或值和通知长时间延迟

RxJS Observables 的 Promise.all 行为?

promise使用

promise!

学习promise

关于promise