我使用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_call的属性,即使我在构造函数中声明了它
另一种方式:
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获得的输出已经完美完成。有人能帮助我吗?我犯了什么错。提前谢谢。
这里可以看到一个stackblitz示例。
我不确定这是否是原因,但您并没有等待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;
}
更新:
您可以添加自定义验证器。禁止名称为Mark
,如果您写入禁止名称,则输入不会保存此值:
@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;
};
}
这里可以看到一个例子。
Angular Custom Validations包含不同的范围,因此您制作的第一个示例不起作用。
由于您使用了"箭头函数",第二个示例确实有效。因为您的自定义验证是异步的,所以您需要返回一个可观察的。看看下面的
第一种选择:
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
}
)
);
}
第二种选择:
this.nameValidator.bind(this(是神奇的发生的地方
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
}
)
);
}