提问人:Anna 提问时间:8/19/2023 最后编辑:nullromoAnna 更新时间:8/19/2023 访问量:31
Angular 反应形式的验证器无法正常工作?
validator in angular reactive form not working properly?
问:
我有这个服务,我正在尝试验证邮政编码字段,但是(结果? 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')])])],
});
答:
0赞
Yong Shun
8/19/2023
#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')],
],
});
- (可选)将执行提供的所有验证可以省略并替换为:
Validators.compose()
CLIENT_GENERAL_FORM_VALIDATORS = this.formBuilder.group({
zip: [
'',
[
Validators.required,
Validators.pattern(/^\d{5}(-)?(\d{4})?$/),
],
[this.addressService.createValidator('zip')],
],
});
- 另一个问题是,在方法中,从条件返回的将始终返回。对于您的方案,您正在尝试通过迭代数组来提交多个请求。您应该使用
forkJoin
运算符来触发并等待所有可观察对象完成,然后使用switchMap
发出一个新的 Observable,其中包含之前的任何可观察对象。checkZipInAllStates
Observable
if
true
states
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);
}
}
评论