角反应形式的验证器无法正常工作?

问题描述 投票:0回答:1

我有这项服务,我正在尝试验证邮政编码字段,但是 (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')])])],
    });
angular validation asynchronous angular-reactive-forms
1个回答
0
投票
  1. 您应该根据 [Angular FormControl 构造函数签名重载 #4] 将
    asyncValidatorFn
    放在第三个参数中。否则
    asynValidatorFn
    将无法正常工作。
CLIENT_GENERAL_FORM_VALIDATORS = this.formBuilder.group({
  zip: [
    '',
    Validators.compose([
      Validators.required,
      Validators.pattern(/^\d{5}(-)?(\d{4})?$/),
    ]),
    [this.addressService.createValidator('zip')],
  ],
});
  1. (可选)将执行所提供的所有验证的
    Validators.compose()
    可以省略并替换为:
CLIENT_GENERAL_FORM_VALIDATORS = this.formBuilder.group({
  zip: [
    '',
    [
      Validators.required,
      Validators.pattern(/^\d{5}(-)?(\d{4})?$/),
    ]),
    [this.addressService.createValidator('zip')],
  ],
});
  1. 另一个问题是,在
    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);
  }
}

演示@StackBlitz

© www.soinside.com 2019 - 2024. All rights reserved.