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

Angular 2 custom validation not calling inside of component function

我正在尝试使用自定义验证器查找重复的经销商名称。经销商名称数据来自网络服务。我有经销商服务来获取经销商数据。我正在使用它在组件内的 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 - 由于您的自定义验证器 validDelarNameasync,它 必须 作为第三个。参数,像这样:

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

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

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

或者如果您愿意:

this.validDelarName.bind(this)

3 - validDelarName的签名错误,必须是这样的:

validDelarName(control: AbstractControl) { ... }

4 - async 验证器 等待或 PromiseObservable 而你只 returning null | errorObjforEach 里面,哪个什么都没做。

解法:

您可以使用 map 运算符代替 subscribe(或者如果您愿意,可以使用 Promise)并让 Angular 完成他的工作。

要在 array 中搜索特定值,我建议您使用 Array#some。如果它在数组中找到键入的文本并自动停止循环,它将 returns 为真,否则它将为 return 假。

基于此,可以return error object or 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 object 的所有键(正如您所做的那样),因为您只想比较dealername.

6(小错误)- 你在 retrun null; 中有错别字,应该是 return null; :).

7(感谢@yurzui)-return {valid:true;} should be return { valid: true };


提示:

1 - 不需要 Validators.compose,您可以只传递一个 array,或者如果它是单个验证器,则在两个参数(第二个和第三个)中传递验证器本身。

2 - Validators.pattern 接受一个 RegExp,所以你可以使用它。

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

样本:

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

此外,请注意这里并非所有符号都需要转义(我去掉了不需要的转义)。

FULL DEMO