在我们的应用程序中,我们有一个页面,只有在设置了特定状态时才应导航到该页面,我们在 Page C 上将其称为 requiredState$
。
用户必须在前往所述页面的途中选择一些值,这样他就可以在Page B 上设置requiredState$
。用户可以多次启动此选择循环,这意味着他将多次导航到 Page C。起点是页面A。从页面 A 导航到页面 B 后,状态会重置。
顺序是页面A(重置状态)->页面B(选择状态)->页面C(需要状态)->页面A
等。
为了避免在未设置 requiredState$
的情况下导航到 Page C,我们在 Page C 的管道中进行了以下检查:
this.intermediateObservable$ = this.requiredState$.pipe(
tap((requiredState) => {
if (!requiredState) {
// navigate back to Page B (*)
this.cancelPipe$.next();
}
}),
// ...
takeUntil(this.cancelPipe$),
// ...
);
而 cancelPipe$
是一个简单的 Subject
。
Observable this.intermediateObservable$
用在三个地方
产生显示的数据
this.data$ = this.intermediateObservable$.pipe(...)
然后由 HTML 模板中的
async
管道订阅当用户选择一个类别时
this.intermediateObservable$.pipe(
take(1)
).subscribe((someData) => {
// filter out desired category and save to state service
});
- 当用户想要显示信息数据时
this.modalContent$ = this.intermediateObservable$.pipe(
// map information to show
);
同样,this.modalContent$
通过 async
管道传递给模态
问题
第一个周期,一切正常。用户在 Page B 上设置状态,导航到 Page C 做更多的事情,然后返回到 Page A。现在,如果他开始第二个周期,他将导航到 Page B(就在导航之前,重置所需状态)。这似乎触发了来自 Page C 的标记行 (*),导致“双重导航”到 Page B。
这怎么可能?我知道 pipe()
创建了一个新的可观察对象,这意味着它们共有三个。
- 和 3. 不是直接订阅的,而是后来通过
async
管道订阅的,应该自动处理。 - 使用了
take(1)
操作符,据我理解应该是之后直接退订。
最佳答案
答案很简单:在成功的情况下我们没有调用 this.cancelPipe$.next()
,这意味着 takeUntil()
没有被调用并且管道仍然活跃。
关于angular - 尽管在异步管道订阅的管道中,Observable 似乎仍然存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64642175/