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

validator in angular reactive form not working properly?

提问人:Anna 提问时间:8/19/2023 最后编辑:nullromoAnna 更新时间:8/19/2023 访问量:31

问:

我有这个服务,我正在尝试验证邮政编码字段,但是(结果? 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-reactive-forms

评论


答:

0赞 Yong Shun 8/19/2023 #1
  1. 您应该根据 [Angular FormControl 构造函数签名重载 #4] 将 放在第三个参数中。否则将无法正常工作。asyncValidatorFnasynValidatorFn
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. 另一个问题是,在方法中,从条件返回的将始终返回。对于您的方案,您正在尝试通过迭代数组来提交多个请求。您应该使用 forkJoin 运算符来触发并等待所有可观察对象完成,然后使用 switchMap 发出一个新的 Observable,其中包含之前的任何可观察对象。checkZipInAllStatesObservableiftruestatestrue
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