angular4物料表中的自定义验证器结果错误

angular4物料表中的自定义验证器结果错误,angular,angular-material-table,angular-custom-validators,mat-form-field,Angular,Angular Material Table,Angular Custom Validators,Mat Form Field,我使用的是angular4材质表。在那里,我尝试添加自定义输入验证 我已经在那个里创建了独立的验证器服务,我调用了自定义函数,根据api结果命中我的api,它将抛出有效或无效的输入 这是我的密码谁能告诉我我犯了什么错误 import { Injectable } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; import { ValidatorService }

我使用的是angular4材质表。在那里,我尝试添加自定义输入验证 我已经在那个里创建了独立的验证器服务,我调用了自定义函数,根据api结果命中我的api,它将抛出有效或无效的输入

这是我的密码谁能告诉我我犯了什么错误

import { Injectable } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { ValidatorService } from 'angular4-material-table';
import { AbstractControl } from '@angular/forms';
import { ApiCallService } from 'api.service';

    @Injectable()
    export class MatTableValidatorService implements ValidatorService {
        constructor( private api_call: ApiCallService) {  
        }
       getRowValidator(): FormGroup {
        return new FormGroup({
          'name': new FormControl(null, [Validators.required, this.nameValidator]),
          });
      }
        nameValidator(control: AbstractControl): { [key: string]: boolean } | null {
            this.api_call
            .api_function(parameter)
            .subscribe(data => {
              const arrayVal = data.response;
              if(arrayVal.length > 0)
              {
                return {'dnsCheck': true}
              }
              return null;
          });
            return null;
        }

    }
这个函数返回错误:无法读取api_调用的属性,即使我在构造函数中声明了它

还有另一种方式:

   public nameValidator = (control: AbstractControl) => {
         this.api_call
            .api_function(parameter)
            .subscribe(data => {
              const arrayVal = data.response;
              if(arrayVal.length > 0)
              {
                return {'dnsCheck': true}
              }
              return null;
          });
        };
这种方法有效,但即使输入有效或无效,它也总是抛出错误。我已经用控制台检查了输出,似乎从api得到的结果已经完美完成了。谁能帮我一下我犯了什么错。 提前谢谢


我不确定这是否是一个原因,但您并没有等待api调用的结果。您的代码总是返回
null
。所以我们需要等待API调用的结果:

async nameValidator(control: AbstractControl): { [key: string]: boolean } | null {  
    const result = await this.api_call.api_function(parameter);
    const arrayVal = result.response;

    if (arrayVal.length > 0)
          return {'dnsCheck': true}

    return null;
}
更新:

您可以添加自定义验证器。禁用名称为
标记
,如果您写入禁用名称,则输入将不会保存此值:

@Injectable()
export class PersonValidatorService implements ValidatorService {
  getRowValidator(): FormGroup {
    return new FormGroup({
      'name': new FormControl(null, [Validators.required, forbiddenNameValidator()])

      });
  }
}

export function forbiddenNameValidator(): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} | null => {    
    const forbidden =  'Mark';
    console.log(`forbidden name is `, forbidden);
    return (forbidden == control.value) ? {'forbiddenName': {value: control.value}} : null;
  };
}

角度自定义验证包含不同的范围,因此您创建的第一个示例不起作用

第二个示例在您使用“箭头函数”后确实有效。 因为自定义验证是异步的,所以需要返回一个可观察的。 看看下面的例子

第一种选择:

nameValidator = (control: AbstractControl): Observable<{ [key: string]: boolean } | null> => {
    return this.api_call
        .api_function(parameter)
        .pipe(
            map(
                data => {
                    const arrayVal = data.response;
                    return arrayVal && arrayVal.length > 0 ? { 'dnsCheck': true } : null
                }
            )
        );
}
nameValidator=(控件:AbstractControl):可观察=>{
返回此.api\u调用
.api_函数(参数)
.烟斗(
地图(
数据=>{
const arrayVal=data.response;
返回arrayVal&&arrayVal.length>0?{'dnsCheck':true}:null
}
)
);
}
第二种选择:

这就是神奇的地方

getRowValidator(): FormGroup {
    return new FormGroup({
        'name': new FormControl(null, {
            asyncValidators: [this.nameValidator.bind(this)],
            validators: [Validators.required],
        }),
    });
}

nameValidator(control: AbstractControl): Observable < { [key: string]: boolean } | null > {
    return this.api_call
        .api_function(parameter)
        .pipe(
            map(
                data => {
                    const arrayVal = data.response;
                    return arrayVal && arrayVal.length > 0 ? { 'dnsCheck': true } : null
                }
            )
        );
}
getRowValidator():FormGroup{
返回新表单组({
“名称”:新FormControl(null{
asyncValidators:[this.nameValidator.bind(this)],
验证器:[验证器。必需],
}),
});
}
nameValidator(控件:AbstractControl):可观察<{[键:字符串]:布尔值}空>{
返回此.api\u调用
.api_函数(参数)
.烟斗(
地图(
数据=>{
const arrayVal=data.response;
返回arrayVal&&arrayVal.length>0?{'dnsCheck':true}:null
}
)
);
}

谢谢你的帮助。仍然收到此错误DnsDashboardComponent.html:29错误类型错误:无法读取push.src/app/@core/matTable-validator.service.ts.MatTableValidatorService.namevidatory未定义的属性“api_call”,当您声明字段时添加“bind”函数,如下所示:new FormControl(null,[Validators.required,this.namevidator.bind(本条)。通过这种方式,您可以明确表示自定义验证函数与组件具有相同的作用域。我将编辑注释。我现在更新了代码错误已消失,但api未在映射中返回值。我尝试控制api命中但没有响应。您可以检查吗?我更新了注释。查看AsyncValidatorsHanks以共享。我尝试h async await一件事api函数不返回值我们是否需要订阅或管道、映射以获取数据以及as值不返回core.js:12584错误:未捕获(承诺中):TypeError:无法读取未定义TypeError的属性“length”错误:无法读取MatTableValidatorService上未定义的属性“length”。(mI刚刚添加了toPromise now,它的工作状态仍然是formcontrol,右输入返回错误。我在arrayval>0中给了控制台。它返回true,但仍然是formcontrol出错span@KavyaShree你能举个例子吗?