我可以使用Subject来制作自定义异步验证器吗?

时间:2017-11-12 18:01:52

标签: angular angular-forms angular-validation angular-observable

我是否有机会通过主题实现这一目标?暂时我只用一个承诺来实现这个目标。所以我打电话给解决方法,这是正确的。

我试图做以下事情。

forbiddenEmail(control: FormControl): Observable<any> {

    const obs = new Subject();
    setTimeout(() => {
      if (control.value === 'test@test.com') {
        obs.next({'emailIsForbidden': true});
      } else {
        obs.next(null);
      }
    }, 2000);
    return obs;
  }

在这里,我试图在值为test@test.com时发出事件,否则为null,因为Angular中的文档说明了验证器。 我试图模拟让我们说一个后端服务,这就是为什么我实现setTimeout fucntion并给出2秒的超时。 现在的问题是,当我检查放置验证器的输入元素(电子邮件输入元素)时,总是显示类ng-pending。 所以,由于某种原因我不订阅它我知道。但我怎么样?

这是我在FormGroup中调用验证器的地方。

ngOnInit() {
    this.signupForm = new FormGroup({
      'userData': new FormGroup({
        'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
        'email': new FormControl(null, [Validators.required, Validators.email], this.forbiddenEmail.bind(this))
      }),
      'gender': new FormControl('male'),
      'hobbies': new FormArray([])
    });
  }

3 个答案:

答案 0 :(得分:1)

根据文档,您可以通过返回observable来实现: Direct Connect Gateways User Guide

我试图用代码示例来证明它,但看起来它不会起作用......

看起来像角度问题本身,在这里报道:https://angular.io/api/forms/AsyncValidatorFn

答案 1 :(得分:1)

你需要完成你的观察:

setTimeout(() => {
  if (control.value === 'test@test.com') {
    obs.next({'emailIsForbidden': true});
  } else {
    obs.next(null);
  }
  obs.complete();
}, 2000);

但这可以用更简单的方式定义:

forbiddenEmail2(control: FormControl): Observable<any> {
  const result = control.value === 'test@test.com' ? {'emailIsForbidden': true} : null;
  return Observable.of(result).delay(2000);
}

这也更正确,因为它实际上验证了调用验证器时的输入,而不是在2秒后验证输入。在更现实的用例中:您将立即获得输入,并将其发送到后端。

演示:https://github.com/angular/angular/issues/13200

答案 2 :(得分:0)

当然,只需返回asObservable()即可。

forbiddenEmail(control: FormControl): Observable<any> {
  const subject = new Subject();

  setTimeout(() => {
    if (control.value === 'test@test.com') {
      subject.next({ emailIsForbidden: true });
    } else {
      subject.next(null);
    }
  }, 2000);

  return subject.asObservable();
}