2017-07-07 121 views
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 }); 
     } 
    }); 
} 

回答

0

利用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,會破壞邏輯, ,我將不得不在商店中引入一些屬性以區分網絡負載微調器和路由負載微調器 或其他解決方法 –