【问题标题】:How to use an Observable in Angular route guard?如何在 Angular 路由保护中使用 Observable?
【发布时间】:2019-04-26 21:47:13
【问题描述】:

在我的角度路由模块中,当它是默认主页时,我使用基本导航,现在在某些情况下,我想决定导航哪条路线。这就是我的应用路由的外观。

 { path: '', redirectTo: 'home1', canActivate: [homepageGuard], pathMatch: 'full' },
  { path: 'home1', loadChildren: './lazyloadedmodule1' },
  { path: 'home2', loadChildren: './lazyloadedmodule2' },
  { path: 'home3', loadChildren: './lazyloadedmodule3' },
  { path: 'basehome', loadChildren: './lazyloadedmodule4' }

现在在我的路由守卫中,我这样调用订阅。

canActivate(): Observable<any> | boolean {
    return this._myService.getCurrentApp().subscribe(
      (r) => {
        if(r === 'app1'){
          //navigate to app1homepage
        } else if (r === 'app2') {
          //navigate to app2homepage
        } else {
          // navigate to base homepage
        }
      },
      (e) => {
        console.log(e);
        return false;
      }
    );
  }

这就是我调用 API 时服务的外观。

public getCurrentApp(): Observable<any> {
    return this.http.get(this.apiBaseUrl + 'getApp').pipe(
      catchError((err: HttpErrorResponse) => {
        return throwError(err.error.errorMessage);
      }));
  }

首先,路由守卫没有将值作为订阅,因为我相信它只期望一个布尔值,但我会以字符串的形式得到响应。如何确保在第一个页面加载期间调用 API 并相应地重定向它?

【问题讨论】:

    标签: javascript angular angular-router angular-router-guards


    【解决方案1】:

    我提出这样的建议。使用服务并返回真/假并导航。

    canActivate(): Observable<any> | boolean {
    return this._myService.getCurrentApp()
        pipe(
            tap((response) => {
                if(r === 'app1'){
                    this.router.navigate([...]);
                } else if (r === 'app2') {
                    this.router.navigate([...]);
                } else {
                    this.router.navigate([...]);
                }
            }),
            map(() => false),
            catchError((e)=> of(false))
        )
        }
      }

    坦率地说,这不是解决此类问题的最佳方法。我相信更好的方法是为不同的路径创建不同的 AuthGuards,这些路径将执行 API 请求并检查是否允许它进入特定的路由。然后只返回 false 或 true。

    【讨论】:

    • 是的,但那是用户尝试导航的时候。这基本上适用于应用加载后的主页。
    • 嘿,我尝试在应用路由中包含这个,像这样 { path: '', redirectTo: 'home', canActivate: [HomepageNavigateGuard], pathMatch: 'full' },并且还包含在 appmodule 的提供者部分,我不确定为什么它甚至没有在加载时点击调试器?
    • 那么到底是什么问题?
    • 我的意思是没有错误,一切都很好。好的,当我把守卫放在 home1 路线而不是 '' 路线上时,我发现它起作用了。
    • 好的 ;) 所以如果答案是正确的,请接受这个 ;) 如果不是,我准备提供帮助
    【解决方案2】:

    你的守卫不应该订阅 observable,路由器会这样做......

    所以你基本上需要返回一个返回真或假值的 observable。

    如果你要重新路由,那么你显然永远不会返回 true....试试这个....

    canActivate(): Observable<boolean> {
        return this._myService.getCurrentApp().pipe(
            tap(r => {
                if(r === 'app1'){
                    //navigate to app1homepage
                } else if (r === 'app2') {
                   //navigate to app2homepage
                } else {
                   // navigate to base homepage
                }
            }),
            catchError(r => of(false))
        );
    }
    

    【讨论】:

    • 嘿,我尝试在应用路由中包含这个,像这样 { path: '', redirectTo: 'home', canActivate: [HomepageNavigateGuard], pathMatch: 'full' },并且还包含在 appmodule 的提供者部分,我不确定为什么它甚至没有在加载时点击调试器?
    猜你喜欢
    • 2017-02-11
    • 1970-01-01
    • 2018-01-27
    • 2021-11-22
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多