2017-12-02 94 views
2

我想在flatMap中有一個條件檢查第一個observable返回的內容。如果條件不滿足,我想打破並導航到不同的頁面。rxjs條件裏面的平面圖

this.service.getData(id) 
    .flatMap((data) => { 
    if (!data) { 
     return Observable.throw(new NoDataFoundError()); 
    } 
    return Observable.forkJoin(
     this.service.getData2(id2), 
     this.service.getData3(id3), 
    ); 
    }) 
    .subscribe(
    ([data2, data3]) => { 
     this.data2= data2; 
     this.data3= data3; 
    }, 
    (err) => { 
     if (err instanceof NoDataFoundError) { 
     this.router.navigate(...); 
     } 
    } 
); 

目前我拋出具體的錯誤和追趕它不過因爲它不是的代碼,可能會引發錯誤的唯一片和如果不結垢,我不喜歡這種解決方案。

我想過filter或takeWhile操作符,但是我將無法執行重定向。

我也想過要返回Observable.of,而不是拋出(在第4行),但是接下來我將不得不在做訂閱的時候也這樣做。

+0

代碼看起來相當不錯原樣。你能否詳細說明你的擔憂?您可以使用幾種不同的模式,但這取決於還在發生什麼。 –

回答

6

您可以在.flatMap內執行this.router.navigatereturn Observable.empty()。這樣您將有一個if聲明。

.flatMap(data => { 
    if (!data) { 
    this.router.navigate(...); 
    return Observable.empty(); 
    } 
    return (...); 
}) 

但通常觀測量應該是懶惰和純(無副作用),這將使他們預測和輕鬆完成取景構圖。副作用只能由用戶執行。

在特定情況下,這似乎是正確的解決辦法是把這個邏輯路徑後衛,喜歡這裏描述 - https://stackoverflow.com/a/39162538/3772379

+2

感謝您的回答,並且對於遲到的回覆感到抱歉。 我不確定Observable.empty(),因爲那樣我就不得不在IF中訂閱了。我得到Observables應該是純粹的,但我認爲我的用例很常見。我終於從canActivate獲得靈感,但將其改爲[resolver](https://angular.io/guide/router#fetch-data-before-navigating)。感謝幫助。 – kit

+0

不,這就是訣竅。當你返回'.empty()' - 沒有任何東西會被髮射,這意味着你不需要在訂閱中處理它。 –

+0

在我特別的問題中,我可以使用canActivate/resolver將層次中的提取邏輯向上移動。如果我沒有任何提及的機制,我該如何繼續。我能想到的唯一解決方案是使用訂閱內訂閱。 – kit