javascript 重定向至“使用canActivate guard时无法工作”诊断树

zaqlnxep  于 2023-02-18  发布在  Java
关注(0)|答案(2)|浏览(104)

redirectTo属性在我的Angular 2应用中不起作用。我的app.routing.ts中有以下路线:

const routes: Routes = [
  { path: '', redirectTo: '/page/1', pathMatch: 'full' },
  { path: 'page', loadChildren: 'app/modules/page/page.module#PageModule' }
]

export const routing = RouterModule.forRoot(routes);

然后,在我的page.routing.ts中,我有以下内容:

const pageRoutes: Routes = [
  { path: ':id', component: PageComponent, canActivate: [LoginGuard] }
];

export const pageRouting = RouterModule.forChild(pageRoutes);

每次我访问主页时,它都会显示LoginComponent一秒钟,然后消失。不过,它应该重定向到PageComponent
为什么没有发生这种情况?为什么LoginComponent在用户已经登录的情况下被加载(即使只有很短的一秒钟)?
下面是我的LoginGuard

@Injectable()
export class LoginGuard implements CanActivate {

  constructor(private af: AngularFire, private router: Router) {}

  canActivate(): Observable<boolean> {
    return this.af.auth.map(auth =>  {
      if (auth === null) {
        this.router.navigate(['/login']);
        return false;
      } else {
        return true;
      }
    }).first();
  }

}

**EDIT:**临时地,我将LoginComponent更改为在用户登录时重定向到PageComponent。不过,我仍然想知道为什么redirectTo不工作。

zkure5ic

zkure5ic1#

我不知道为什么会发生这种情况,但我相信如果您在加载PageModule之前检查LoginGuard,它将工作。
app.routing.ts

const routes: Routes = [
  { path: '', redirectTo: '/page/1', pathMatch: 'full' },
  { 
    path: 'page', 
    // Call the guard before the module is loaded
    canLoad: [ LoginGuard ]
    loadChildren: 'app/modules/page/page.module#PageModule' 
  }
]

export const routing = RouterModule.forRoot(routes);

登录防护

@Injectable()
export class LoginGuard implements CanActivate, CanLoad {

  constructor(private af: AngularFire, private router: Router) {}

  // Add this method to validade the canLoad
  canLoad(route: Route): Observable<boolean> {
    return this.canActivate();
  }  

  canActivate(): Observable<boolean> {
    return this.af.auth.map(auth =>  {
      if (auth === null) {
        this.router.navigate(['/login']);
        return false;
      } else {
        return true;
      }
    }).first();
  }

}
sshcrbum

sshcrbum2#

您不应在防护装置内导航

这是因为你直接从你的路线守卫中调用this.router.navigate(['/login']);,它在当前运行的路线上初始化一个新的路线导航。我的猜测是/login'的一方获胜,因为另一方必须延迟加载模块(需要一些时间)。但加载完成后,它随后更改为该路由,因此出现“ Flink ”登录弹出窗口。
您不应该在一个Guard中导航,相反,如果您想重定向/改变路线,您应该总是返回boolean(允许导航真/假)或UrlTree。Guard返回值,然后路由器将在正在进行的/触发的导航中为您改变导航到提供的UrlTree,您不会得到任何比赛。
所以像这样改变你的方法,它就会正确地工作。

canActivate(): Observable<boolean|UrlTree> {
  return this.af.auth.map(auth =>  {
    if (auth === null) {
      return this.router.parseUrl('/login');
    }
    return true;
  }).first();
}

你应该看到它像这样,如果你在几个路由守卫中调用this.router.navigate,那么路由器将不知道导航到哪里,通过返回一个UrlTree,这个问题就解决了。

相关问题