簡體   English   中英

如何在Angular 2 Guards的canActivate()中使用可觀察對象

[英]How to use an observable in angular 2 guards' canActivate()

我已經為我的angular2 rc5應用程序創建了一個身份驗證保護。

我也在使用redux商店。 在該商店中,我保留用戶的身份驗證狀態。

我了解到守衛可以返回可觀察到的或應許的( https://angular.io/docs/ts/latest/guide/router.html#!#guards

我似乎無法找到一種讓守衛等待存儲/可觀察對象更新的方法,並且只有該更新之后才返回守衛,因為存儲的默認值始終為false。

第一次嘗試:

@Injectable()
export class AuthGuard implements CanActivate {

  @select(['user', 'authenticated']) authenticated$: Observable<boolean>;

  constructor() {}

  canActivate(): Promise<boolean> {

    return new Promise((resolve, reject) => {

      // updated after a while ->
      this.authenticated$.subscribe((auth) => {

        // will only reach here after the first update of the store
        if (auth) { resolve(true); }

        // it will always reject because the default value
        // is always false and it takes time to update the store
        reject(false);

      });

    });

  }

}

第二次嘗試:

@Injectable()
export class AuthGuard implements CanActivate {

  @select(['user', 'authenticated']) authenticated$: Observable<boolean>;

  constructor() {}

  canActivate(): Promise<boolean> {

    return new Promise((resolve, reject) => {

      // tried to convert it for single read since canActivate is called every time. So I actually don't want to subscribe here. 
      let auth = this.authenticated$.toPromise(); 

      auth.then((authenticated) => {

        if (authenticated) { resolve(true); }

        reject(false);

      });

      auth.catch((err) => {
        console.log(err);
      });

  }

}

當您訂閱一個可觀察對象時,您可以提供一個回調函數。 在下面的示例中,我將其稱為CompleteGet CompleteGet()僅在成功返回數據而不是錯誤的get時調用。 您可以在回調函數中放置任何所需的邏輯。

getCursenByDateTest(){
 this.cursenService
   .getCursenValueByDateTest("2016-7-30","2016-7-31")
   .subscribe(p => {
     this.cursens = p;
     console.log(p)
     console.log(this.cursens.length);
   },
   error => this.error = error,
   () => this.CompleteGet());
}

completeGet() {
   // the rest of your logic here - only executes on obtaining result.
}

我相信您也可以將.do()添加到可觀察的訂閱中以完成相同的操作。

您需要做的就是強迫可觀察對象進行更新:

canActivate(): Observable<boolean> {
    return this.authenticated$.take(1);
}

編輯:canActivate等待可觀察的源完成,並且(很可能,我不知道幕后發生了什么), authenticated$觀察的發出.next() ,而不是.complete()

來自文檔: http : //reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-take
.take(1)方法首先獲取可觀察到的源發出的值,然后完成

Edit2:我只是看着您粘貼的代碼片段,而我是對的-可觀察到的store.select()永遠不會完成,它總是發出.next

訂閱不返回Observable。 但是,您可以像這樣使用map運算符:

this.authenticated$.map(
    authenticated => {
        if(authenticated) {
            return true;
        } 
    return false;
    }
 ).first() // or .take(1) to complete on the first event emit

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM