我如何才能取消这个内部使用combineLatest的Angular 7异步验证器



我知道其中涉及的工具有pipetimerswitchMapdebounceTimedistinctUntilChanged,甚至更多,但我不知道如何使它们与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();
});
});
};
}
}

我如何才能取消跳动,使它不会在750毫秒内运行API调用一次以上?

这就是最终对我有效的方法:

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};
}
}));
}));
};
}
}

最新更新