带依赖项的Angular2自定义验证器

带依赖项的Angular2自定义验证器,angular,dependency-injection,dependencies,custom-validators,Angular,Dependency Injection,Dependencies,Custom Validators,在Angular 2中,我试图创建自己的自定义验证器 我已经创建了自己的CustomValidators类,它实现了validator接口 import { FormControl } from "@angular/forms"; import { MyhttpService } from "./myhttp.service"; import { Response } from "@angular/http"; import { Injectable, Directive } from '@an

在Angular 2中,我试图创建自己的自定义验证器

我已经创建了自己的CustomValidators类,它实现了validator接口

import { FormControl } from "@angular/forms";
import { MyhttpService } from "./myhttp.service";
import { Response } from "@angular/http";
import { Injectable, Directive } from '@angular/core';


@Injectable()
export class CustomValidators{

constructor(private _http : MyhttpService){

}

public api(c : FormControl)
{
    // Run 
    this._http.get("/expenses/email?email=" + c.value).subscribe((res:Response) => {
        if(res.status === 200){
            // email exists
            return null;
        } else {
            return {"email" : true}
        }
    });
}
如果我使api成为一个静态方法,那么我可以使用它成功地使用该类

this._formDetails = fb.group({
  "managerEmail" : ["", [Validators.required, CustomValidators.api] ]
});
不过,这当然是一个静态方法,因此我无法访问任何构造函数值,因为构造函数尚未运行

因此,我找不到一种实现具有依赖项的自定义验证器的方法,必须有一种方法

我尝试将CustomValidator列为提供者,以便我的类接收该类的实例化对象

类型“typeof CustomValidators”上不存在属性“api”

我是否以正确的方式提供课程?为什么该方法不存在?

尝试以下方法:

this._formDetails = fb.group({
  "managerEmail" : ["", Validators.required, CustomValidators.api]
});
Validators.required
是一个同步验证器,但是您的
CustomValidators.api
是一个异步验证器


根据,每个表单控件都应该使用状态、同步验证器,然后是异步验证器来指定。

我使用Angular v5.2.9验证数据库中是否已经存在用户名时遇到了类似的情况。我的用例有点不同——我使用的是一个很容易缓存的小用户列表,我的数据是使用@ngrx库集中的,但我希望它能有所帮助

从Validator类开始,构造函数负责发出获取请求并将结果缓存在一个可观察的静态列表中;实际验证方法将使用此可观察列表来查看用户名是否已在使用中

import { Injectable } from '@angular/core'
import { FormControl } from '@angular/forms'

import { Store } from '@ngrx/store'

import { Observable } from 'rxjs/observable'
import 'rxjs/add/operator/take'
import 'rxjs/add/operator/map'

import { myActions } from '../@ngrx/actions/some.actions'
import { State, selectIds } from '../@ngrx/reducers/some.reducer'


@Injectable()
export class CustomValidators {

  static ids_in_use$: Observable<string[]>;

  constructor(
    private store: Store<State>
  ) {
    this.store.dispatch({ type: myActions.FETCH_REQUEST })
    CustomValidators.ids_in_use$ = this.store
      .select( selectIds )
      .map( ( id_list: string[] ) => id_list.map( id => id.toLowerCase() ) )
  }

  static api( control: FormControl ) {
    return new Promise(
      ( resolve ) => {
        CustomValidators.ids_in_use$
          .take( 1 )
          .subscribe(
            id_list => {
              if( id_list.indexOf( control.value.toLowerCase() ) === -1 ) 
                resolve( null )
              else resolve({ 'email-in-use': true })
            })
      })
}
这就是我如何确保验证程序构造函数中的代码被执行的原因,尽管主要验证逻辑是静态方法。类似地,我可以想象,您可以使用这个实例来使用在您的案例中进行验证之前特别需要的任何实例属性/方法,从而发出http请求。然后,我可以在FormBuilder组中使用静态验证方法(请记住,除非您调用它,否则您的tslint将警告您,
“customValidators”已声明,但其值从未被读取

最后,必须为可注入服务声明一个提供者,这可以在
@Component
装饰器中完成:

@Component({
  ...,
  providers: [ CustomValidators ]
})

我现在遇到了同样的问题。您找到解决方案了吗?您的答案中有一个错误:
this.\u formDetails=fb.group({“managerEmail”:[“”,Validators.required],[CustomValidators.api]})就是你的意思。但这并不是他的问题的答案。
this._formDetails = fb.group({
  'managerEmail': [ '', Validators.required, CustomValidators.api ]
})
@Component({
  ...,
  providers: [ CustomValidators ]
})