我正在开发一个有角度的应用程序,我遇到的情况是:一个可观察到的信号,表示已从远程获取了一些数据(dataFetchedEvent$
),以及一种使用该远程数据并侦听用户更改的形式({{ 1}})。
formChanges$
使用此代码可以正常工作,但在每次 const dataFetchedEvent$ = this.event.asObservable()
.pipe(
tap((fetchedData) => {
this.createFormControls(fetchedData); // creates the reactive form control based on the data fecthed from remote
}),
takeUntil(this.componentDestroyed) // fired when in the ngOnDestroy of the component
);
const formChanges$ = this.form.valueChanges // listen form changes
.pipe(
switchMap((formDataRaw) => this.formatData(formDataRaw)), // transform data
takeUntil(this.componentDestroyed)
);
dataFetchedEvent$.subscribe();
formChanges$.subscribe(
(formattedFormData) => {
// do stuff...
}
);
更改控件时,每次dataFetchedEvent$
都会触发formChanges$
订阅,因此我想避免这种情况。
我的目标是仅在创建或更新表单控件后才侦听表单更改。
我尝试了多种解决方案,但每种解决方案都有一定的局限性:
使用 skipUntil
this.createFormControls(fetchedData)
此解决方案避免了在创建控件时 const formChanges$ = this.form.valueChanges // listen form changes
.pipe(
skipUntil(dataFetchedEvent$),
switchMap((formDataRaw) => this.formatData(formDataRaw)), // transform data
takeUntil(this.componentDestroyed)
);
流的多次发射,并且在销毁组件并重新创建组件时(例如,当用户更改页面并返回时)工作,但是对于skipUntil {{ 1}}在第一次发出后不再订阅,在某些情况下,formChanges$
必须再次发出并更新表单控件。
与 concat
dataFetchedEvent$
在这种情况下,dataFetchedEvent$
流从未被订阅,我认为这是因为dataFetchedEvent $未完成。
具有最新组合
const formChanges$ = this.form.valueChanges // listen form changes
.pipe(
switchMap((formDataRaw) => this.formatData(formDataRaw)), // transform data
tap((formattedFormData) => {
// do stuff...
}),
takeUntil(this.componentDestroyed)
);
concat(dataFetchedEvent$, formChanges$).subscribe();
这不是我要查找的,因为在创建控件时仍会发出formChanges $流。
使用 mergeMap或switchMap
formChanges$
这是第一次执行,或者如果销毁并重新创建了该组件,但是如果combineLatest(dataFetchedEvent$, formChanges$).subscribe([val1, val2] => { // do stuff... });
在第一次更新表单控件后第一次发出const dataFetchedEvent$ = this.event.asObservable()
.pipe(
tap((fetchedData) => {
this.createFormControls(fetchedData); // creates the reactive form control based on the data fecthed from remote
}),
mergeMap(() => formChanges$),
takeUntil(this.componentDestroyed) // fired when in the ngOnDestroy of the component
);
dataFetchedEvent$.subscribe();
之后再次发出。对于dataFetchedEvent$
,其行为是相同的。
哪种方法是实现我的目标的最佳方法?
------编辑------
在我的示例中,代码是通用且经过简化的。
这是表单控件
formChanges$
唯一更改的组是类别,当发出switchMap
时,意味着新类别已从远程感染,并且我使用form = this.fb.group({
tourLength: this.fb.group({
length: [false]
}),
types: this.fb.group({
type: [false]
}),
categories: this.fb.group({}),
languages: this.fb.group({
lang: [false]
}),
prices: this.fb.group({
opt: [false]
})
});
(即先前的dataFetchedEvent$
_createControlsCategories()
}
每个类别都绑定到视图中的复选框。
答案 0 :(得分:0)
签出
const dataFetchedEvent$ = this.event.asObservable()
.pipe(
tap((fetchedData) => {
this.createFormControls(fetchedData);
}));
dataFetchedEvent$
.pipe(
switchMap(() => formChanges$.pipe(takeUntil(dataFetchedEvent)),
takeUntil(this.componentDestroyed)
).subscribe();