我想在异步加载 Angular 路由配置时显示一个加载器,但有时这些加载器可以非常快,而加载器只会在屏幕上闪烁一瞬间。
我希望仅在加载器在一段时间后仍未完成加载时才显示加载器。我首先想到的是使用delay(250)
。当使用所需的配置导航到该页面时,这种方法有效,但如果我刷新该页面,加载器似乎总是会在屏幕上短暂闪烁
这是我现在正在做的事情
private isLoadingRouteConfig = false;
readonly isLoadingRouteConfig$ = this.router.events.pipe(
delay(250), //if the config loads very quickly, don't even show this
map((ev) => {
if (ev instanceof RouteConfigLoadStart) {
this.isLoadingRouteConfig = true;
} else if (ev instanceof RouteConfigLoadEnd) {
this.isLoadingRouteConfig = false;
}
return this.isLoadingRouteConfig;
}),
);
@if (isLoadingRouteConfig$ | async) {
<app-loader />
}
我怎样才能让它按预期工作?我想在 250 毫秒后显示加载器,但如果已经完成加载,则跳过此步骤。
我相信闪烁是因为在发出true和false之前会有延迟,所以即使事件彼此之后瞬间发生,仍然需要 250ms 才能改变值。
下面的可观察流将通过执行以下操作来解决此情况:
可能还有其他方法可以处理这个问题,比如使用delayWhen 。另外,我删除了isLoadingRouteConfig的设置。您可以随意使用 将其添加到流的末尾
tap(x => this.isLoadingRouteConfig = true)
,但我建议您尽量避免使用它。如果您不能使用展平运算符,那么请考虑尝试toSignal。您的延迟操作符还会延迟 RouteConfigLoadEnd 事件,我猜您并不想要这样。尝试使用计时器代替延迟,并在收到 RouteConfigLoadEnd 时使用 switchMap 取消计时器:
也许这样的事情会对你有用:
这个想法是,当你收到你关心的事件时,你用它
switchMap
来“切换”到一个新的可观察源。当
RouteConfigLoadStart
你发射一个可观察物体时,它立即发射false
,然后在 250 毫秒后发射true
。当
RouteCofigLoadEnd
你发出一个可观察对象时,它会false
立即发出。如果
RouteConfigLoadEnd
在 250 毫秒之前收到,true
则永远不会发出该值,因为源可观察对象已被切换。