Angular 6-预期验证程序返回承诺或在异步验证程序中可观察到

Angular 6-预期验证程序返回承诺或在异步验证程序中可观察到,angular,angular6,Angular,Angular6,在我的Angular 6应用程序中,我有一个异步验证器,用于检查键入的电子邮件是否已经注册,但现在我得到了“预期验证器将返回承诺或可观察”,我真的不知道为什么 import { UserService } from '../user/service/user.service'; import { AbstractControl, ValidationErrors, AsyncValidator } from '@angular/forms'; import * as validationUtil

在我的Angular 6应用程序中,我有一个异步验证器,用于检查键入的电子邮件是否已经注册,但现在我得到了“预期验证器将返回承诺或可观察”,我真的不知道为什么

import { UserService } from '../user/service/user.service';
import { AbstractControl, ValidationErrors, AsyncValidator } from '@angular/forms';
import * as validationUtils from '../validation/validation-utils';
import { Injectable } from '@angular/core';
import { of, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class EmailExistValidator implements AsyncValidator {
  constructor(private userService: UserService) {
  }

  validate(emailControl: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
    const email = emailControl.value;

    if (new RegExp(validationUtils.emailRegex).test(email)) {
      this.userService
      .checkIfEmailExist(email)
      .pipe(
        map(
        (data) => {
          return {emailExist: true};
        },
        (error) => {
          return null;
        }
      ));
    }
      return of(null);
  }
}
编辑2018年8月17日 正如@Paulie所建议的,我将formbuilder中的验证器声明从.bind更改为指向validate函数,并对他的命题进行了一些调整,现在一切都正常了

最终代码:

寄存器-component.ts

  createForm(): FormGroup {
    return this.formBuilder.group({
      email: ['',
      [Validators.required, Validators.email],
      [EmailExistValidator.bind(this)]],
      username: ['', [Validators.required,
        Validators.pattern(validationUtils.usernameRegex)]],
      password: ['', [Validators.required,
        Validators.pattern(validationUtils.passwordRegex)]],
      repeatPassword: ['', [Validators.required]]
  }, {
    validator: EqualPasswordValidator.validate
  });
  }
  constructor(
    private formBuilder: FormBuilder,
    private userService: UserService,
    private emailExistsValidator: EmailExistsValidator,
    private usernameExistsValidator: UsernameExistsValidator) { }

  ngOnInit() {
    this.registerForm = this.createForm();
  }

  createForm(): FormGroup {
    return this.formBuilder.group({
      email: ['',
      [Validators.required, Validators.email],
      [this.emailExistsValidator.validate]],
      username: ['', [Validators.required,
        Validators.pattern(validationUtils.usernameRegex)],
        [this.usernameExistsValidator.validate]],
      password: ['', [Validators.required,
        Validators.pattern(validationUtils.passwordRegex)]],
      repeatPassword: ['', [Validators.required]]
  }, {
    validator: EqualPasswordValidator.validate
  });
  }
email-exists-validator.ts

import { UserService } from '../user/service/user.service';
import { AbstractControl, ValidationErrors, AsyncValidator } from '@angular/forms';
import * as validationUtils from './validation-utils';
import { Injectable } from '@angular/core';
import { of, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class EmailExistsValidator implements AsyncValidator {
    static userService: UserService;

  constructor(private userService: UserService) {
    EmailExistsValidator.userService = userService;
  }

  validate(emailControl: AbstractControl): Promise<{ [key: string]: any } | null>
  | Observable<{ [key: string]: any } | null>  {

    const email = emailControl.value;

    if (new RegExp(validationUtils.emailRegex).test(email)) {
        return EmailExistsValidator.userService
        .checkIfEmailExist(email)
        .pipe(
          map(data => ({emailExist: true})),
          catchError(error => of(null))
        );
      }

      return of(null);

}
}
从“../user/service/user.service”导入{UserService};
从'@angular/forms'导入{AbstractControl,ValidationErrors,AsyncValidator};
从“/validation utils”导入*作为validationUtils;
从“@angular/core”导入{Injectable};
从“rxjs”导入{of,Observable};
从“rxjs/operators”导入{map,catchError};
@注射的({
providedIn:'根'
})
导出类EmailExistsValidator实现AsyncValidator{
静态用户服务:用户服务;
构造函数(私有用户服务:用户服务){
EmailExistsValidator.userService=userService;
}
验证(emailControl:AbstractControl):承诺
|可观察{
const email=emailControl.value;
if(新RegExp(validationUtils.emailRegex.test(email)){
返回EmailExistsValidator.userService
.checkIfEmailExist(电子邮件)
.烟斗(
映射(数据=>({emailExist:true})),
catchError(error=>of(null))
);
}
返回(空);
}
}

您必须从
checkIfEmailExist
返回可观测值:

// ...
return this.userService
  .checkIfEmailExist(email)
  .pipe(
// ...

RxJS的映射不接受第二个函数参数
我猜你想要这样的东西:

if (new RegExp(validationUtils.emailRegex).test(email)) {
  return this.userService
  .checkIfEmailExist(email)
  .pipe(
    map(data => {emailExist: true}),
    catchError(error => null)
  );
}

return of(null);

添加多个验证器时,需要将验证器添加到另一个第三个括号“[]”中。如下图所示:

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

有控制台错误吗
.bind(此)
可能会使
userService
注入器发生故障。试着把它去掉。是的,你是对的。在本例中,Bind导致了错误。我用最终工作版本编辑了我的问题。+1表示返回(null)。我仍然需要准确地理解它的功能,但它为我修复了错误。我返回的是null。
of(null)
创建RxJS Subject(您可以
.subscribe()
)对象,它总是将
null
(或您在参数中指定的其他值/值序列)发送给订阅服务器。