自定义输入控件中的Angular2 /同步+异步验证器

时间:2018-10-17 15:20:52

标签: angular typescript angular-forms angular-validation

我需要基于输入标志提供异步验证,以便可以触发也可以不触发验证。表单是模板驱动的,所以我想这就是为什么我不能使用指令的原因。

在以下验证逻辑中是否可以执行此操作?

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构造函数中定义验证逻辑或将其作为指令以模板驱动的形式。

0 个答案:

没有答案