【问题标题】:Angular ValidatorFn returns, but does not block FormAngular ValidatorFn 返回,但不阻止 Form
【发布时间】:2019-08-23 15:43:28
【问题描述】:

我为我的表单构建了一个自定义验证器,它返回预期的 ValidationErrors 对象。

ValidateDirectory(clientId: string): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
            const ret: ValidationErrors = { isValidDirectory: true };
            if (control.value == null || control.value === '') {
                return ret;
            }
            this.service.getList(clientId, control.value).subscribe((res) => {
                if (res.technicalRetCode !== 0) {
                    console.log(ret);
                    return ret;
                }
                return null;
            });
            return null;
        };
    }

我用 console.log 行证明了这一点,这实际上记录了我的对象。

验证器附加在ngOnInit 中的 Validators.required 之外

ngOnInit() {
  ...
  this.fourthFormGroup = this._formBuilder.group({
      dateipfad: ['', {validator: Validators.compose([Validators.required, this.directoryValidator.ValidateDirectory(this.clientID)]), updateOn: 'blur'}]
    });
  ... 
}

问题是:所需的验证器按预期工作,但我的自定义验证器只记录。

我已经尝试了很多,比如使用 validators 和数组而不是 Validators.compose,调整了我的 Validator 方法来设置 control.setErrors(ret) 一些其他的东西,没有任何效果。

我觉得有一个很简单的解决方案,但我就是找不到......

编辑 1: 我创建了一个堆栈闪电战https://stackblitz.com/edit/angular-ysyb9i?file=src%2Fapp%2Fapp.component.html

说明:输入接受任何字符串,在取消选择时验证开始。 如果 Input 为“false”,则应通过返回 const ret: ValidationErrors = { isValidDirectory: true }; 将输入设置为无效,任何其他字符串都应有效并返回 null

两个结果都记录在控制台上,因此您可以检查它。如果输入无效,它应该在下面显示一个通知 div(不太确定,只是添加它以供此 stackblitz 显示)

【问题讨论】:

  • 您能否创建一个堆栈闪电战来复制您的问题?
  • 当然,需要一些时间
  • @yurzui 我用 stackBlitz 链接编辑了我的问题。这是我第一次使用它,所以请怜悯;)
  • 试试这个更新的 stackblitz stackblitz.com/edit/angular-vjgqex?file=src/app/… 它对我有用。请注意,如果您的验证器是异步的,那么您应该将其放入异步验证器
  • 感谢您的帮助!这有助于初始验证,但在您输入“false”后,您不会得到无效标志。我还没有使用异步验证器,但似乎解决方案是异步执行此验证器。

标签: angular typescript angular-reactive-forms angular2-form-validation


【解决方案1】:

如果您的验证器中的代码是异步的,您应该使用异步验证器。

this.fourthFormGroup = this._formBuilder.group({
  dateipfad: ['', {
    validators: [Validators.required],
    asyncValidators: [this.directoryValidator.ValidateDirectory(this.clientID)],
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                    put it here
    updateOn: 'blur'
  }]
});

验证器应该返回AsyncValidatorFn 接口,你应该订阅observable,而是映射到你想要的值。 Angular 会自动订阅你的 observable。

ValidateDirectory(clientId: string): AsyncValidatorFn {
  return (control: AbstractControl): 
             Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
    const ret: ValidationErrors = { isValidDirectory: true };

    if (control.value == null || control.value === '') {
      return of(ret);
    }

    return this.service.getList(clientId, control.value).pipe(map((res: any) => {
      if (res.technicalRetCode !== 0) {
        return ret;
      }

      return null;
    }));
  };
}

Forked Stackblitz

另外请注意,只有在所有同步验证器都返回 null 时才会触发异步验证器。所以你不会从一开始就看到错误,因为你有同步的required 验证器。

【讨论】:

    猜你喜欢
    • 2019-05-05
    • 2021-09-11
    • 1970-01-01
    • 2014-08-01
    • 2021-03-25
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多