我有这项服务,我正在尝试验证邮政编码字段,但是 (result ? null : { IsInvalid: true }) 永远不会执行。
反应形式工作正常还是逻辑/用法错误?
@Injectable({
providedIn: 'root'
})
export class AddressService {
public states = []
public zipCodeValid = new Subject<boolean>();
public zipCodeValid1 = new BehaviorSubject<boolean>(false);
constructor(private httpService: HttpService) {
this.states = ['AL', 'FL']
}
createValidator(fieldName: string): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return this.checkZipInAllStates(control.value)
.pipe(
map((result: boolean) =>
result ? null : { IsInvalid: true }
)
);
};
}
checkZipInAllStates(value: string) {
if (this.states && value) {
return of(this.states.some((state) => {
return this.checkZipCodeBelongsStateObservable(state, value)
}))
}
else {
return of(false)
}
}
checkZipCodeBelongsStateObservable(state: string, zipCode: string) {
return this.httpService.httpGet(environment.coreApiEndpoint + `zipCodesMaster/zipCodeBelongsState/${zipCode}/${state}`)
.pipe(map((response) => {
return response.Data
}))
}
}
CLIENT_GENERAL_FORM_VALIDATORS = this.formBuilder.group({
'zip': ['', Validators.compose([Validators.required, Validators.pattern(/^\d{5}(-)?(\d{4})?$/), Validators.composeAsync([this.addressService.createValidator('zip')])])],
});
asyncValidatorFn
放在第三个参数中。否则 asynValidatorFn
将无法正常工作。CLIENT_GENERAL_FORM_VALIDATORS = this.formBuilder.group({
zip: [
'',
Validators.compose([
Validators.required,
Validators.pattern(/^\d{5}(-)?(\d{4})?$/),
]),
[this.addressService.createValidator('zip')],
],
});
Validators.compose()
可以省略并替换为:CLIENT_GENERAL_FORM_VALIDATORS = this.formBuilder.group({
zip: [
'',
[
Validators.required,
Validators.pattern(/^\d{5}(-)?(\d{4})?$/),
]),
[this.addressService.createValidator('zip')],
],
});
checkZipInAllStates
方法中,从 Observable
条件返回的 if
将始终返回 true
。对于您的场景,您尝试通过迭代 states
数组来提交多个请求。您应该与 forkJoin
运算符一起触发并等待所有可观察量完成,然后使用 switchMap
发出一个新的可观察量,其中任何先前的可观察量是 true
。checkZipInAllStates(value: string): Observable<boolean> {
if (this.states && value) {
let observables$: Observable<boolean>[] = this.states.map((state) =>
this.checkZipCodeBelongsStateObservable(state, value)
);
return forkJoin(observables$).pipe(
switchMap((values: boolean[]) => of(values.some((x) => x)))
);
} else {
return of(false);
}
}