首先,让我解释一下我想要实现的目标。
所有这个例子都在this plunker
中复制我有一个可以使用服务显示的应用程序加载器。这个加载器显示在我的顶部栏中,这是我全局布局的一部分。
我想在获取数据时显示加载程序。例如,我有一个带有一些参数
的路线const routes = [
{path: 'test/:id', component: TestPageComponent}
]
导航到/test/2
时,会创建组件并使用异步服务加载有关项2
的一些数据。
在实际加载数据之前,它会告诉LoaderService
显示加载程序。
ngOnInit(): void {
// Add or remove .delay(0) to make it work or not.
this.item$ = this.route.paramMap/*.delay(0)*/.switchMap((params) => {
this.loaderService.isShown$.next(true)
this.id = params.get('id')
// Start with undefined, so the component is cleared before loading the new item
return this.fakeService
.load(this.id)
.do(() => this.loaderService.isShown$.next(false))
.startWith(undefined)
})
}
问题是
Expression has changed after it was checked
这是因为route.paramMap
observable在第一次创建组件时同步解析。
使用RxJS运算符delay(0)
强制执行异步行为可以轻松避免此问题。但它感觉不是正确的方法......
您可以使用the plunker进行游戏,只需点击go to X
即可显示TestComponent
。第一次,它触发错误,然后,当导航到另一个项目时,组件不会被销毁,因此paramMap
是异步的,并且不会触发错误。您可以点击reset
返回主页并销毁TestComponent
。
我在Angular repo上没有发现任何关于此事的问题,但也许我只是在搜索问题时表现不好:/