我们有一个非常嵌套的反应式 Angular,其中所有 FormControls 都位于 FormArray 内的 FormGroup 内。一些 FormControl 具有异步验证器来检查值的唯一性。每次动态地将另一个 FormGroup 添加到 FromArray 或从 FromArray 中删除时,都会调用所有异步验证器。
例如:
FormGroup.addControl
FromGroup.removeControl
假设我有 5 个带有异步验证器的 FormControl,然后如果我动态添加另外 4 个 FormControl(addControl),则会调用 4*5=20 次异步验证器,而且很多时候这些 Http 调用中很少有被取消。我假设 Angular 必须在某个地方使用 switchMap,这会导致异步验证器发出的一些 Http 调用被取消。
有人可以解释一下吗?如何解决这个问题或者 Angular 中异步验证器的一些最佳实践是什么?
在 Angular 中,当您有带有异步验证器的反应式表单时,Angular 确实使用 switchMap 来管理正在进行的可观察流。当触发新的验证时,此行为可能会导致正在进行的 HTTP 请求被取消。
以下是处理此问题并提高异步验证器性能的一些策略:
去抖请求: 使用去抖时间来延迟异步验证器的执行,以便它们不会在每次更改时立即触发。这有助于减少不必要的 HTTP 请求的数量。
this.formGroup.get('controlName')?.setAsyncValidators(
debounceTime(300), // Adjust the debounce time as needed
asyncValidatorFunction
);
直到操作员: 当组件被销毁或表单控件被移除时,使用 takeUntil 运算符来完成正在进行的 observable。这有助于避免不必要的持续请求已删除的表单控件。
private ngUnsubscribe = new Subject<void>();
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
// In your async validator function
asyncValidatorFunction(control: AbstractControl): Observable<ValidationErrors | null> {
return someObservable.pipe(
takeUntil(this.ngUnsubscribe)
);
}
表单组清理: 确保在销毁表单组或删除表单控件时正确清理表单控件和异步验证器。
ngOnDestroy() {
this.formGroup.clearAsyncValidators();
this.formGroup.updateValueAndValidity(); // Trigger validation update
}
优化异步验证器: 检查您的异步验证器逻辑以确保其尽可能高效。尽量减少不必要的请求,并考虑服务器端分页或过滤(如果适用)。
// Example: Server-side filtering
asyncValidatorFunction(control: AbstractControl): Observable<ValidationErrors | null> {
const value = control.value;
return this.service.checkUniqueness(value);
}
应用这些策略应该可以帮助您优化 Angular 反应式表单中异步验证器的行为,并减少取消的 HTTP 请求的数量。根据您的具体用例和要求调整去抖时间和其他参数。