如何在Angular路线防护中使用Observable?

时间:2019-04-26 21:47:13

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

在我的角度路由模块中,当默认页面现在处于某种条件下时,我想确定要导航的路线时,我正在使用基本导航。这就是我的应用程序路由外观。

 { 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);
      }));
  }

首先,routeguard不会将值作为订阅,因为我相信它只是一个布尔值,但是我将以字符串形式返回响应。如何确保在首页加载过程中调用API并进行相应的重定向?

2 个答案:

答案 0 :(得分:1)

我提议像这样的事情。使用服务并返回true / false和导航。

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))
    )
    }
  }

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

答案 1 :(得分:0)

您的警卫不应该订阅可观察的东西,路由器会这样做。...

因此,您基本上需要返回一个返回true或false值的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))
    );
}