Как я могу отменить этот асинхронный валидатор Angular 7, который использует внутренне объединение? - PullRequest
0 голосов
/ 11 декабря 2018

Я вроде понимаю, что инструменты, вовлеченные в это, будут pipe, timer, switchMap, debounceTime, distinctUntilChanged и, возможно, больше, но я не могу понять, как заставить их работать сcombineLatest.

Следующий валидатор получает список адресов электронной почты, разделенных запятыми, и выполняет API-вызов для каждого из них, чтобы проверить, существует ли это сообщение в базе данных клиентов.

import {AbstractControl, AsyncValidatorFn, ValidationErrors, ValidatorFn} from "@angular/forms";
import {combineLatest} from "rxjs";
import {Observable} from "rxjs/internal/Observable";

import {UtilityApiService} from "../../services/api/utility-api.service";

/**
 * The email address must exist in the database and belong to a customer.
 * It works both with a single email or a comma separate list of emails. In case of a list, it will only validate
 * as a success if ALL emails belong to a customer.
 * @returns {ValidatorFn}
 * @constructor
 */
export class CustomerEmailCsvValidator {
    public static createValidator(internalApiService: UtilityApiService): AsyncValidatorFn {
        return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
            return new Observable((observer) => {
                if (!control.value) {
                    observer.next(null);
                    return;
                }

                const emails: string[] = control.value.split(",").map(email => email.trim());
                const observables: Observable<boolean>[] = emails.map(email => {
                    return internalApiService.isCustomerEmail(email);
                });

                combineLatest(observables).subscribe((responses: boolean[]) => {
                    if (responses.every(value => value)) {
                        // All emails exist and belong to customers. Therefore no error.
                        observer.next(null);
                    } else {
                        // One or more emails do not exist in the database, or do not belong to a customer.
                        // This is an error for this validator.
                        observer.next({customerEmail: true});
                    }
                    observer.complete();
                });
            });
        };
    }
}

Как я могу отказаться, чтобы он не выполнял вызовы API более одного раза за 750 мс?

1 Ответ

0 голосов
/ 12 декабря 2018

Вот что у меня получилось:

import {AbstractControl, AsyncValidatorFn, ValidationErrors, ValidatorFn} from "@angular/forms";
import {combineLatest, of, timer} from "rxjs";
import {Observable} from "rxjs/internal/Observable";
import {map, switchMap} from "rxjs/operators";

import {UtilityApiService} from "../../services/api/utility-api.service";

/**
 * The email address must exist in the database and belong to a customer.
 * It works both with a single email or a comma separated list of emails. In case of a list, it will only validate
 * as a success if ALL emails belong to a customer.
 * @returns {ValidatorFn}
 * @constructor
 */
export class CustomerEmailCsvValidator {
    public static createValidator(internalApiService: UtilityApiService): AsyncValidatorFn {
        return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
            return timer(750).pipe(switchMap(() => {
                if (!control.value) {
                    return null;
                }

                const emails: string[] = control.value.split(",").map(email => email.trim());
                const observables: Observable<boolean>[] = emails.map(email => {
                    return internalApiService.isCustomerEmail(email);
                });

                return combineLatest(observables).pipe(map((responses: boolean[]) => {
                    if (responses.every(value => value)) {
                        // All emails exist and belong to customers. Therefore no error.
                       return null;
                    } else {
                        // One or more emails do not exist in the database, or do not belong to a customer.
                        // This is an error for this validator.
                        return {customerEmail: true};
                    }
                }));
            }));
        };
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...