Angular 2自定义验证未调用组件函数

时间:2017-06-17 12:03:02

标签: angular angular2-forms angular-reactive-forms

我正在尝试使用自定义验证器查找重复的经销商名称。经销商名称数据来自网络服务。我有经销商服务来获取经销商数据。我在组件内的validDelarName函数中使用它进行经销商重复验证。我在FromGroup Validators上声明它但它没有被调用。

Form Group Validator - declare

name: ['', Validators.compose([Validators.required, Validators.maxLength(128),Validators.pattern('[a-zA-Z0-9\\s\\-\\,\\.\\&\\(\\)]+'),(control:FormControl)=>this.validDelarName])],

验证功能。它也存在于组件中。

 validDelarName(FormControl){   
  const dealer = this.dealer.getviewdealer().subscribe( //getting data using webservices
  (data) => {       
     data.forEach(items => {
      for (var key in items) {
        if (items.hasOwnProperty(key)) {

          if(control.value == items['dealername']){
            return {valid:true;}
          }
          else{
            retrun null;
          }

        }
      }
     });
  }

);
 }

1 个答案:

答案 0 :(得分:3)

首先,您的代码中存在很多错误,请列举它:

1 - 由于您的自定义验证器validDelarNameasync,因此必须为第3个。参数,像这样:

name: [
  '', 
  [
    Validators.required, 
    Validators.maxLength(128),
    Validators.pattern('[a-zA-Z0-9\\s\\-\\,\\.\\&\\(\\)]+')
  ],
  (control: AbstractControl) => this.validDelarName // Fix later
]

2 - 您必须将控件或上下文传递给自定义验证器,如下所示:

(control: AbstractControl) => this.validDelarName(control)

或者如果您愿意:

this.validDelarName.bind(this)

3 - validDelarName的签名错误,必须如下:

validDelarName(control: AbstractControl) { ... }

4 - async 验证器等待或PromiseObservable并且您只在null | errorObj内返回forEach {1}},哪一个人没有做任何事情。

解决方案:

您可以使用subscribe运算符(或者如果您希望使用Promise)而不是map,而是让Angular完成他的工作。

要在array中搜索特定值,我建议您使用Array#some。如果它在数组中找到键入的文本并且会自动停止循环,它将返回true,否则它将返回false。

基于此,您可以返回错误 object或null,如下所示:

validDelarName(control: AbstractControl) {
  return this.dealer.getviewdealer().map(data => {
    const hasItem: boolean = data.some(item => control.value === item['dealername']);

    return hasItem ? { valid: true } : null;
  });
}

5 - 正如您在上面所看到的,您不需要迭代data 对象的所有键(因为您正在做),因为您只是想要比较dealername

6(轻微错误) - 您在retrun null;中输入错误,应为return null; :)。

7(@yurzui的积分) - return {valid:true;} should be return { valid: true };

<强>提示:

1 - Validators.compose不是必需的,您可以在两个参数(第2和第3个)中传递array,或者它是单个验证器,验证器本身)。

2 - Validators.pattern接受RegExp,因此您可以使用它。

为什么呢?不是使用双斜线转义符号,而是只能转义一个斜杠和IMO,它更具可读性。

示例

Validators.pattern(/^[a-zA-Z0-9\s-\,\.&\(\)]+$/)

另外,请注意,此处并非所有符号都需要转义(我会删除不必要的转义)。

FULL DEMO