angular4 material table 中的自定义验证器结果错误
custom validator in angular4 material table results error
我正在使用 angular4-material-table 。在那里我尝试添加自定义输入验证
我在那里创建了单独的验证器服务我调用了自定义函数来根据 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;
}
}
这个 returns 错误:无法读取 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 得到的输出已经完美完成。任何人都可以帮助我我的错误是什么。
提前致谢。
我不确定这是否是一个原因,但是您并不是在等待 api 电话的结果。你的代码总是 return 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;
}
更新:
您可以添加自定义验证器。 Forbidden name是Mark
,如果你写forbidden name,那么input不会保存这个值:
@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 自定义验证包含不同的范围,因此您制作的第一个示例不起作用。
自从您使用 'arrow function' 后,第二个示例确实有效。
因为您的自定义验证是异步的,所以您需要 return 一个可观察的。
看看下面
第一个选项:
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(这)是奇迹发生的地方
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
}
)
);
}
我正在使用 angular4-material-table 。在那里我尝试添加自定义输入验证 我在那里创建了单独的验证器服务我调用了自定义函数来根据 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;
}
}
这个 returns 错误:无法读取 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 得到的输出已经完美完成。任何人都可以帮助我我的错误是什么。 提前致谢。
我不确定这是否是一个原因,但是您并不是在等待 api 电话的结果。你的代码总是 return 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;
}
更新:
您可以添加自定义验证器。 Forbidden name是Mark
,如果你写forbidden name,那么input不会保存这个值:
@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 自定义验证包含不同的范围,因此您制作的第一个示例不起作用。
自从您使用 'arrow function' 后,第二个示例确实有效。 因为您的自定义验证是异步的,所以您需要 return 一个可观察的。 看看下面
第一个选项:
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(这)是奇迹发生的地方
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
}
)
);
}