Валидаторы Angular2 / Sync + Async в пользовательском контроле ввода - PullRequest
0 голосов
/ 17 октября 2018

Мне нужно предоставить асинхронную проверку, основанную на флаге ввода, чтобы проверка могла запускаться или не запускаться.Форма управляется шаблоном, поэтому, я думаю, именно поэтому я не могу использовать директиву.

Есть ли способ сделать это в следующей логике проверки?

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 или как директиву в управляемой шаблоном форме.

...