我需要基于输入标志提供异步验证,以便可以触发也可以不触发验证。表单是模板驱动的,所以我想这就是为什么我不能使用指令的原因。
在以下验证逻辑中是否可以执行此操作?
component.ts
export class DataTextInputComponent implements OnChanges, ControlValueAccessor, Validator {
/**
[... ]all correct implementations for value accessor, etc]
*/
public validate(c: FormControl): {} | null {
return this.errors = (this.isReadOnly) ? null : this.customValidate(c);
}
private customValidate(c: FormControl): {} | Observable<any> | Promise<any> | null {
if ( c.touched ) {
if ( !this.hasNoValue(c) ) {
// email
if ( this.type == 'email' ) {
const emailRegEx = new RegExp('^[a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$');
if ( !emailRegEx.test(c.value) ) {
return { 'email': true };
} else {
// >>>> THIS IS WHERE IT GOES SOUTH <<<<
if ( this.checkUnique ) {
return this.uniqueEmail.validate(c);
}
}
}
// max
if ( this.maxlength && c.value.length > parseInt(this.maxlength, 10)) {
return { 'maxlength': true };
}
// min
if ( this.minlength && c.value.length < parseInt(this.minlength, 10)) {
return { 'minlength': true };
}
}
if ( this.required && this.hasNoValue(c) ) {
return { 'required': true };
}
if ( this.match && this.required && (c.value != this.match.value) ) {
return { 'nomatch': true };
}
}
return null;
}
}
asyncvalidator service.ts
@Injectable()
export class UniqueEmailDirective implements AsyncValidator {
constructor(private api: DbService ) {}
validate( ctrl: AbstractControl ): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
const notUnique: ValidationErrors = { 'notUnique': true };
return this.api.checkUserEmail({email: ctrl.value})
.toPromise()
.then(isUnique => ( isUnique === true ) ? null : notUnique);
}
}
this.api.checkUserEmail
是一个POST请求,可以正确响应。问题出在组件上,它忽略了验证。我知道为什么,但是我只是无法解决“如何”正确实现它。
编辑:最好的情况是通过一些@Input()标志而不是某些父组件在此自定义组件中实现异步验证逻辑,其中必须在FormGroup构造函数中定义验证逻辑或将其作为指令以模板驱动的形式。