我正在开发 Angular 14 应用程序,在同一组件中有 3 个独立的表单,每个表单都有一个名为“rut”的字段。因此,当用户在这 3 个表单中的任何一个上的 rut 字段上输入一些数据时,我必须对一个服务执行 http 调用以带回数据。
listenForRutChanges() {
const opRutControl = this.operationsFormGroup.get('rut')!;
const legalRutControl = this.legalFormGroup.get('rut')!;
const invoiceRutControl = this.invoiceFormGroup.get('rut')!;
opRutControl?.valueChanges
.pipe(
debounceTime(300),
filter(() => opRutControl.valid),
)
.subscribe((value) => {
this.rutSubject.next({ value, formGroup: this.operationsFormGroup });
});
legalRutControl?.valueChanges
.pipe(
debounceTime(300),
filter(() => legalRutControl.valid),
)
.subscribe((value) => {
this.rutSubject.next({ value, formGroup: this.legalFormGroup });
});
invoiceRutControl?.valueChanges
.pipe(
debounceTime(300),
filter(() => invoiceRutControl.valid),
)
.subscribe((value) => {
this.rutSubject.next({ value, formGroup: this.invoiceFormGroup });
});
}
所以正如你所看到的,我抓取了这 3 个不同表单的表单字段,在 valuechanges 上我等待了一段时间,然后我有了一个 BehaviourSubject。 BehaviourSubject 实现是这样的:
rutSearch() {
this.searchSubs = this.rutSubject
.pipe(
filter(({ value }) => value !== ''),
distinctUntilChanged(),
switchMap(({ value, formGroup }) =>
this.clientService.getDetailsByRut(value).pipe(
map((clientResponse) => ({ clientResponse, formGroup })),
catchError(() => of()),
),
),
)
.subscribe(({ clientResponse, formGroup }) => {
const { clientInfo } = clientResponse.data[0];
const { email, fullName: name, phoneNumber: phone } = clientInfo;
formGroup!.patchValue({ name, email, phone }, { emitEvent: false });
});
}
问题在于该服务被调用一次。然后,即使我检测到其他表单字段具有不同的信息,该服务也不再被调用。有任何想法吗?另外,如果您看到可以重构的内容,请告诉我。
提前致谢。
我尝试使用 http 调用来调用普通函数,而不是创建行为主体。但没有成功。
我认为问题在于
switchMap
,也许还有 distinctUntilChanged
中的 rutSearch
。
如果外部可观察量发出,
switchMap
会取消内部可观察量。
尝试以下操作:
filter(({ value }) => value !== ''),
// distinctUntilChanged(), Remove distinctUntilChanged
mergeMap(({ value, formGroup }) // switch switchMap to mergeMap
我认为罪魁祸首是
distinctUntilChanged
,因为它会忽略完全相同的排放。
这是一篇关于
switchMap
、mergeMap
和 concatMap
之间差异的好文章。
https://blog.angular-university.io/rxjs-higher-order-mapping/
简而言之,如果外部可观察量发出,
switchMap
会取消内部可观察量。
mergeMap
不做这种取消行为。
concatMap
不会执行此取消行为,并且内部可观察量的处理顺序与外部可观察量相同。