显示导航装载器微调器延迟角度2+

问题描述:

我是新的角度2+和RxJS,试图习惯RxJS。显示导航装载器微调器延迟角度2+

我展示的路线转变负载微调,但只有当它需要更多的则一定时间,拉特说160毫秒
我有一个负载微调作为一个单独的组件,以订阅NGRX店,所以我显示/隐藏负荷基于疮(showSpinner)值

在我的应用程序根组件飞旋,我订阅了路由器改变事件,并派遣行为(SHOW_SPINNER/HIDE_SPINNER)
所以现在的问题是,有没有更简单的方式来实现它?

这里是我的代码

.... 

export const navigationStreamForSpinnerStatuses = { 
    NAVIGATION_STARTED: 'NAVIGATION_STARTED', 
    NAVIGATION_IN_PROGRESS: 'NAVIGATION_IN_PROGRESS', 
    NAVIGATION_ENDED: 'NAVIGATION_ENDED' 
}; 

....部分

private navigationStartStream; 
private navigationStartStreamWithDelay; 
private navigationFinishStream; 

constructor(private store: Store<IAppState>, private router: Router) { 
    this.navigationStartStream = router.events 
    .filter(event => { 
     return event instanceof NavigationStart; 
    }) 
    .map(() => navigationStreamForSpinnerStatuses.NAVIGATION_STARTED); 

    this.navigationStartStreamWithDelay = this.navigationStartStream 
    .delay(160) 
    .map(() => navigationStreamForSpinnerStatuses.NAVIGATION_IN_PROGRESS); 

    this.navigationFinishStream = router.events 
    .filter(event => { 
     return event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError; 
    }) 
    .map(() => navigationStreamForSpinnerStatuses.NAVIGATION_ENDED); 

    this.navigationStartStream 
    .merge(this.navigationFinishStream) 
    .merge(this.navigationStartStreamWithDelay) 
    .pairwise() 
    .subscribe([previousStatus, currentStatus] => { 
     if (previousStatus !== navigationStreamForSpinnerStatuses.NAVIGATION_ENDED && currentStatus === navigationStreamForSpinnerStatuses.NAVIGATION_IN_PROGRESS) { 
     this.store.dispatch({ type: StateLoaderSpinnerActionsTypes.SHOW_SPINNER }); 
     } else if (previousStatus === navigationStreamForSpinnerStatuses.NAVIGATION_IN_PROGRESS && currentStatus === navigationStreamForSpinnerStatuses.NAVIGATION_ENDED) { 
     this.store.dispatch({ type: StateLoaderSpinnerActionsTypes.HIDE_SPINNER }); 
     } 
    }); 
} 

利用takeUntil运营商取消微调计时器,如果它的时间之前返回。此外,使用timer创建一个热点观察点,以在经过一段时间后触发一个动作。

takeUntil返回源可观察序列的值,直到另一个可观察序列或Promise产生一个值。

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/takeuntil.md

timer返回产生一个值duetime参数已经过去,然后将每个周期之后后可观察到的序列。

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/timer.md

您可以通过在每个流处理直接派遣这里简化你的逻辑。

this.navigationEnd$ = router.events 
    .filter(event => event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError); 

this.navigationStart$ = router.events 
    .filter(event => event instanceof NavigationStart) 
    .subscribe(_ => { 
    Observable.timer(160) 
     .takeUntil(this.navigationEnd$) 
     .subscribe(_ => this.store.dispatch({ type: StateLoaderSpinnerActionsTypes.SHOW_SPINNER }); 
    }); 

this.navigationEnd$.subscribe(_ => this.store.dispatch({ type: StateLoaderSpinnerActionsTypes.HIDE_SPINNER }); 

所以我们所做的是听导航的起点和开始timer为160毫秒。如果导航结束事件发生在定时器之前,则不会显示微调器(takeUntil)。否则,商店行为将被派发,并且微调将显示。无论是否显示微调,在导航完成后,我们会发送隐藏微调操作。

+0

它有什么用? navigationStartStream发出后不会取消整个navigationStartStreamWithDelay流吗? –

+0

@MykhailoI对不起,我试图不要改变太多。请参阅我上面所做的编辑,并让我知道它是否更清晰。 – ChrisG

+0

谢谢,很明显。 我只是想知道如果SHOW_SPINNER没有调度,有没有办法派遣HIDE_SPINNER? 我想重构我的负载微调,以后,使其通用,所以我可以使用它的其他网络请求, 我在考虑在商店中添加一些计数器,并更改showSpinner为假只有计数器为零, 所以额外的HIDE_SPINNER分派,如果没有以前的SHOW_SPINNER,会破坏逻辑, ,我将不得不在商店中引入一些属性以区分网络负载微调器和路由负载微调器 或其他解决方法 –