我正在尝试为博客创建一种不断变化的语言流,总的来说,这是这样的:
Subject
)(即语言更改)的按钮。Firebase
查询正确的页面。如果我分别执行每个步骤,然后用户更改语言,则该查询将不会被触发,因为它不知道事件刚刚发生。因此,我认为这应该是某种嵌套的订阅/可观察的。我错了吗?
我尝试了嵌套订阅,但是没有用。我相信这是由于发现bug所致。现在,这就是我要尝试的:
this.headerService.langChanged.pipe(
map(
(newLang: string) => {
this.db
.collection<AboutMePage>(
this.aboutMeCollectionName,
ref => ref.where('lang', '==', newLang)
)
.valueChanges();
})
)
.subscribe(
value => {
this.aboutMe = value[0]
}
);
headerService.langChanged
是Subject<string>
。
此用例是否有rxjs
运算符? concat
似乎是一个不错的候选者,但是它会等待上一个Observable
结束,但在这种情况下却没有。还有一个事实是,我必须将参数传递到下一个可观察的...
答案 0 :(得分:2)
我认为可以使用concat
,switchMap
,merge
,forkJoin
等中的任何一种为您提供有效的解决方案。这实际上取决于您想要的小东西例如并发。我在这里使用forkJoin
整理了一个Stackblitz的小例子:https://stackblitz.com/edit/angular-xyf8a6
您可以在控制台中看到每个内部Observable
的不同计时,以验证使用forkJoin
的时间,以便只花费最慢的时间即可观察到。
还有我的订阅:
this.langChanged
.subscribe(newLang => {
console.log(`language changed ${newLang}`);
this.cancelLangChange.next();
forkJoin(
this.getUserName(newLang),
this.getUserBio(newLang),
this.getUserCreationDate(newLang)
)
.pipe(takeUntil(this.cancelLangChange))
.subscribe(([username, bio, userCreationDate]) => {
this.aboutMe.username = username;
this.aboutMe.bio = bio;
this.aboutMe.userCreationDate = userCreationDate;
});
});
我还添加了第二个Subject
cancelLangChange
,如果用户仍在加载第一个更改时选择了另一种语言,则该取消是为了取消forkJoin
订阅。
答案 1 :(得分:0)
我基本上通过使用pipe
和map
使其正常工作。 map
操作将使用第一个可观察值基于前者的参数生成另一个。然后,我们以嵌套方式进行订阅,最终将为我们提供所需的数据。
this.aboutMeSubscription = this.headerService.langChanged.pipe(
map(
(newLang: string) => {
return this.db
.collection<AboutMePage>(
this.aboutMeCollectionName,
ref => ref.where('lang', '==', newLang)
)
.valueChanges();
})
)
.subscribe(
langChangedAboutMeObs => {
this.langChangedSubscription = langChangedAboutMeObs
.subscribe(
(value: AboutMePage[]) => {
this.aboutMe = value[0];
}
);
}
);
我也将Subject
更改为BehaviorSubject
,因此甚至在用户执行任何操作之前就已经发出了初始值。最后,重要的是要取消订阅ngOnDestroy
上的两个订阅。