自定义验证器 Angular 2

Mus*_*afa 4 forms validation typescript angular

我编写了一个 web api 函数,它从文本字段中获取用户名并检查用户名是否已被占用。要知道用户名是否可用,我的服务器返回Y是否可用,N如果不可用。

为了验证用户名,我在 Angular2 中使用了 ValidatorFn,因此验证输入。但是,我的验证器功能不起作用。

这是验证器函数:

interface Validator<T extends FormControl> {
  (c: T): { [error: string]: any };
}

function validateUsername(c: string) : ValidatorFn {
  return (this.isAvailable(c)=='Y') ? null : {
    validateUsername: {
      valid: false
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

这是 isAvailable 函数:

private isAvailable(username: string) {
  let usernameAvailable;
  let url = 'URL/api/auth/checkuser/' + username;
  let headers = new Headers();
  headers.append('User', sessionStorage.getItem('username'));
  headers.append('Token', sessionStorage.getItem('token'));
  headers.append('AccessTime', sessionStorage.getItem('AccessTime'));

  let options = new RequestOptions({ headers: headers });

  this.http.get(url, options)
    .subscribe((res: Response) => usernameAvailable);
  return usernameAvailable; //returns Y or N
}
Run Code Online (Sandbox Code Playgroud)

表单生成器:

complexForm: FormGroup;
constructor(private http: Http, fb: FormBuilder) {

  this.complexForm = fb.group({
    'username': [null, Validators.compose([Validators.required, Validators.minLength(5), Validators.maxLength(10), validateUsername(this.complexForm.controls['username'].value)])],
  })
}
Run Code Online (Sandbox Code Playgroud)

validateUsername(this.complexForm.controls['username'].value) 失败,我收到此错误:

[ts] Type '{ validateUsername: { valid: boolean; }; }' is not assignable to type 'ValidatorFn'.   Object literal may only specify known properties, and 'validateUsername' does not exist in type 'ValidatorFn'. (property) validateUsername: {
    valid: boolean;
}
Run Code Online (Sandbox Code Playgroud)

Max*_*kyi 5

您没有正确添加验证器功能。注册时不需要调用函数:

this.complexForm = fb.group({
  'username': [null, Validators.compose(
    [
      Validators.required,
      Validators.minLength(5),
      Validators.maxLength(10),
      validateUsername    <----- don't call it here
    ]
  )],
})
Run Code Online (Sandbox Code Playgroud)

可以看到调用了一些函数:

Validators.minLength(5),
Run Code Online (Sandbox Code Playgroud)

但那是工厂函数调用而不是验证器函数调用。在初始化期间,它们返回ValidatorFn

  /**
   * Validator that requires controls to have a value of a minimum length.
   */
  static minLength(minLength: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
       ...
  }
Run Code Online (Sandbox Code Playgroud)

在官方文档中查看更多信息。

此外,您的验证器似乎是异步的,因此您必须将其传递到异步数组中。而且我认为你不需要Validators.compose. 因此,正确的配置应该是这样的:

this.complexForm = fb.group({
  'username': [null, [
    Validators.required,
    Validators.minLength(5),
    Validators.maxLength(10),
  ], [validateUsername]]
})
Run Code Online (Sandbox Code Playgroud)

关于错误:

类型 '{ 有效:布尔值;}' 不可分配给 type ValidatorFn

您需要使用正确的返回类型ValidationErrors而不是ValidatorFn

function validateUsername(c: string) : ValidationErrors {
  return (this.isAvailable(c)=='Y') ? null : {
    validateUsername: {
      valid: false
    }
  };
}
Run Code Online (Sandbox Code Playgroud)