RXJS:对运行时更改的事件生产者之一的引用
RXJS: Reference to one of event producers changed in runtime
我正在实施以下案例:
我们有多个完全相同的表格。其中一个表单是 'master' 表单,其他表单的内容正在与主表单内容进行比较。目的是检查表单填写是否与 'master' 表单相同。 'master' 和其他形式都在随着时间的推移而改变。
我的实现工作得很好:
注册主表格来源:
public setMasterFormValueSource(masterValue$: Observable<SomeFormValue>, initialValue: SomeFormValue): void {
this._masterFormValue$ = masterValue$.pipe(
startWith(initialValue)
);
}
为其他形式返回 Observable:
public isSameAsForm$(formToCompare$: Observable<SomeFormValue>): Observable<boolean> {
return combineLatest(this._masterFormValue$, formToCompare$).pipe(
map(([formValue1, formValue2]) => areObjectsEqual(formValue1, formValue2)),
distinctUntilChanged()
);
}
问题:
稍后 setMasterFormValueSource
函数被再次调用设置新的 this._masterFormValue$
。问题是所有其他形式都在监听旧 this._masterFormValue$
的变化。有没有办法 'hot swap' 掌握形式价值生产者?
您可以将 this._masterFormValue$
变成可观察对象的可观察对象并使用 switchMap
:
private readonly _masterFormValue$ = new BehaviorSubject<Observable<SomeFormValue>>(of(undefined));
public setMasterFormValueSource(
masterValue$: Observable<SomeFormValue>, initialValue: SomeFormValue
): void {
this._masterFormValue$.next(masterValue$.pipe(
startWith(initialValue)
));
}
public isSameAsForm$(formToCompare$: Observable<SomeFormValue>): Observable<boolean> {
return this._masterFormValue$.pipe(
switchMap(masterForm$ => combineLatest(masterForm$, formToCompare$).pipe(
map(([formValue1, formValue2]) => areObjectsEqual(formValue1, formValue2)),
distinctUntilChanged()
))
);
}
使用 BehaviorSubject
确保我们保留对当前主表单的引用,以便新调用 isSameAsForm$
.
但是,使用嵌套的可观察对象可能会造成混淆。保留对表单本身的引用并在 switchMap
:
中获取 observable 可能更容易
private readonly _masterFormValue$ = new BehaviorSubject<MasterForm>(undefined);
public setMasterFormValueSource(form: MasterForm, initialValue: SomeFormValue): void {
this._masterFormValue$.next(form);
}
public isSameAsForm$(formToCompare$: Observable<SomeFormValue>): Observable<boolean> {
return combineLatest(
this._masterFormValue$.pipe(switchMap(form => form ? form.values$ : [])),
formToCompare$
).pipe(
map(([formValue1, formValue2]) => areObjectsEqual(formValue1, formValue2)),
distinctUntilChanged()
);
}
我正在实施以下案例:
我们有多个完全相同的表格。其中一个表单是 'master' 表单,其他表单的内容正在与主表单内容进行比较。目的是检查表单填写是否与 'master' 表单相同。 'master' 和其他形式都在随着时间的推移而改变。
我的实现工作得很好:
注册主表格来源:
public setMasterFormValueSource(masterValue$: Observable<SomeFormValue>, initialValue: SomeFormValue): void {
this._masterFormValue$ = masterValue$.pipe(
startWith(initialValue)
);
}
为其他形式返回 Observable:
public isSameAsForm$(formToCompare$: Observable<SomeFormValue>): Observable<boolean> {
return combineLatest(this._masterFormValue$, formToCompare$).pipe(
map(([formValue1, formValue2]) => areObjectsEqual(formValue1, formValue2)),
distinctUntilChanged()
);
}
问题:
稍后 setMasterFormValueSource
函数被再次调用设置新的 this._masterFormValue$
。问题是所有其他形式都在监听旧 this._masterFormValue$
的变化。有没有办法 'hot swap' 掌握形式价值生产者?
您可以将 this._masterFormValue$
变成可观察对象的可观察对象并使用 switchMap
:
private readonly _masterFormValue$ = new BehaviorSubject<Observable<SomeFormValue>>(of(undefined));
public setMasterFormValueSource(
masterValue$: Observable<SomeFormValue>, initialValue: SomeFormValue
): void {
this._masterFormValue$.next(masterValue$.pipe(
startWith(initialValue)
));
}
public isSameAsForm$(formToCompare$: Observable<SomeFormValue>): Observable<boolean> {
return this._masterFormValue$.pipe(
switchMap(masterForm$ => combineLatest(masterForm$, formToCompare$).pipe(
map(([formValue1, formValue2]) => areObjectsEqual(formValue1, formValue2)),
distinctUntilChanged()
))
);
}
使用 BehaviorSubject
确保我们保留对当前主表单的引用,以便新调用 isSameAsForm$
.
但是,使用嵌套的可观察对象可能会造成混淆。保留对表单本身的引用并在 switchMap
:
private readonly _masterFormValue$ = new BehaviorSubject<MasterForm>(undefined);
public setMasterFormValueSource(form: MasterForm, initialValue: SomeFormValue): void {
this._masterFormValue$.next(form);
}
public isSameAsForm$(formToCompare$: Observable<SomeFormValue>): Observable<boolean> {
return combineLatest(
this._masterFormValue$.pipe(switchMap(form => form ? form.values$ : [])),
formToCompare$
).pipe(
map(([formValue1, formValue2]) => areObjectsEqual(formValue1, formValue2)),
distinctUntilChanged()
);
}