簡體   English   中英

處理 Angular Router Guard 的多個 Observable

[英]Handle multiple Observables for Angular Router Guard

我是 RxJS 的新手,但似乎符合我的需求。

我想知道是否可以檢索一個監聽兩個BehaviorSubjectObservable

首先我使用 Angular 10 !

我在用

  • 調用我的組件的服務創建 promise 以檢索用戶數據
  • 特定路線上的警衛,也使用先前的服務來確定訪問權限。

為了更好地理解這里是我的配置:

// auth.guard.ts
import { Injectable } from '@angular/core';
import {... } from '@angular/router';
import { from, Observable, Subscription } from 'rxjs';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root',
})
export class AuthGuard implements CanActivate, CanLoad, CanActivateChild {
  constructor(private auth: AuthService) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> {
    return from(this.auth.canActivate());
  }
}
//app-routing.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { SecuredComponent } from './pages/secured/secured.component';
import { AuthGuard } from './auth.guard';


const routes: Routes = [
  // other paths
  {
    path: 'mes-formations',
    component: SecuredComponent,
    canActivate: [AuthGuard]
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
//auth.service.ts
import { Injectable, OnDestroy } from '@angular/core';
import { BehaviorSubject} from 'rxjs';
import { UrlTree } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService implements OnDestroy {
  private userOk$ = new BehaviorSubject(false);
  private isLoading$ = new BehaviorSubject(false);

  constructor(args) {
    this.authenticate();
  }

  async authenticate(): Promise<boolean | UrlTree> {
    // set isLoading$ to true till user request ends
    // fetch user and set userOk$ to true if succeed
  }

  async canActivate(): Observable<boolean | UrlTree> {
    // return true if isLoading is false AND userOk$ true
    // instead redirect outside app
  }
}

我的目標是在以下條件下回答AuthGuard

  • 如果isLoading為真 -> 等待
  • 如果isLoading為 false 且userOk為 true -> true
  • 如果isLoading為 false 並且userOk為 false -> 執行其他操作

怎樣才能做到這一點? 謝謝大家!

嘗試利用combineLatestfiltermap

您可能希望以true而不是false開始isLoading$

canActivate(): Observable<boolean> {
  return combineLatest(
    this.isLoading$,
    this.userOk$,
  ).pipe(
    filter(([isLoading, userOk]) => !isLoading), // wait until isLoading is false (filter emissions while isLoading is true)
    map(([isLoading, userOk) => {
      if (userOk) {  // isLoading is false and userOk is true
        return true;
      } else { // isLoading is false and userOk is false
        // do something else (do whatever else you want to do and return false)
        return false;
      }
   })
  );
}

暫無
暫無

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

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