2016-10-08 98 views
17

我試圖在訂戶中獲得特定值時返回可觀察值,但是我失敗了。如何從訂閱中返回觀察值

這是代碼:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> { 
    // get route to be activated 
    this.routeToActivate = route.routeConfig.path; 

    // get user access levels   
    return this._firebase.isUserAdmin   <-- returns Subscription, not Observable 
     .map(user => user.access_level) 
     .subscribe(access => { 
      // I need to return an observable here 
     }); 
} 

有沒有在角2可觀的資源,所以我不知道從哪裏開始。任何人都可以幫忙嗎?

更新 - >工作版本

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> { 
      // get route to be activated 
      this.routeToActivate = route.routeConfig.path; 

      // get user access levels   
      return this._firebase.isUserAdmin 
       .map(user => { 
        let accessLevel = user.access_level; 

        if (accessLevel === 'admin') { 
         return true; 
        } 

       }).first(); 
     } 
+1

你應該在** rxjs被谷歌搜索觀測量**,而不是NG2。有大量的資源 – drewmoore

+0

謝謝!我嘗試過,但他們沒有采用相同的格式Angular 2使用它們。我想我必須從頭開始學習。 –

+0

您能否進一步解釋這段代碼的上下文?由於'subscribe'返回'Subscription'對象來取消訂閱,因此不可鏈接,因此通常需要執行'observable.subscribe(...);返回可觀察的。 – estus

回答

31

您不能返回從認購可觀察到的,但如果你使用map代替subscribe則返回一個Observable

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> { 
    // get route to be activated 
    this.routeToActivate = route.routeConfig.path; 

    // get user access levels   
    return this._firebase.isUserAdminObservable 
     .map(user => { 
      // do something here 
      // user.access_level; 
      return true; 
     }) 
     .first(); // for the observable to complete on the first event (usually required for `canActivate`) 
     // first needs to be imported like `map`, ... 
} 

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> { 
    // get route to be activated 
    this.routeToActivate = route.routeConfig.path; 

    let subject = new Subject(); 
    // get user access levels   
    this._firebase.isUserAdminObservable 
     .map(user => { 
      let accessLevel = user.access_level; 
      if (accessLevel === 'admin') { 
      subject.emit(true); 
      subject.complete(); 
      } 
      return user; 
     }); 
    return subject; 
} 
+0

嗨,謝謝你的回答!我需要根據值來在subscribe中進行一些處理,然後返回true | false –

+0

您可以在'map'中執行此操作,只需將'user.access_level'更改爲'{user.access_level; ...}'你可以像在普通函數中一樣添加多個語句。確保您在結束時返回結果,否則接收器將不會收到任何內容。 –

+0

我使用這種嘗試: '返回this._firebase.isUserAdmin .MAP(用戶=> { 讓ACCESSLEVEL = user.access_level; 如果(ACCESSLEVEL === '管理員'){ 返回真; } })。first();' 但它不解鎖視圖,所以我猜它不會返回真正的語句。 –

2

我們可以使用toPromise方法將Observable對象轉換爲承諾。 所以代碼可以實現如下:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Promise<boolean> { 
     // get route to be activated 
     this.routeToActivate = route.routeConfig.path; 

     // get user access levels   
     return this._firebase.isUserAdmin 
      .map(user => { 
       return (user.access_level === 'admin'); 
      }).toPromise(); 
    } 
1

你不需要地圖,下面的代碼指定的謂詞和第一投影功能。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> { 
    this.routeToActivate = route.routeConfig.path;  
    return this._firebase.isUserAdminObservable 
     .first((_, index) => index === 0, user => { 
      // do something here 
      // user.access_level; 
      return true; 
     }) 
} 

More on first