如何从警卫队重定向到角的子路线

时间:2018-09-25 23:11:55

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

我如何从父路由的后卫重定向到子路由,同时又保护子路由免受直接访问*?

绝对导航问题,当导航到子路径时,将在循环中再次调用父组件上的防护。

相对导航问题是警卫队正在保护父路线,因此尚没有相对于其导航的“已激活路线”。同样,这可能不会保护子路线。也许同一个警卫也可以与子路由或CanActivateChildren一起使用。

Stackblitz示例:https://stackblitz.com/edit/angular-qbe2a7

路线

const appRoutes: Routes = [
  {
    path: 'foo',
    component: FooComponent,
    canActivate: [ RedirectionGuard ],
    children: [
      {
        path: 'foo-child',
        component: FooChildComponent
      }
    ]
  }
];

canActivate()保持警惕

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {

    console.log('guard: ', route, state, this.route);

    // idea: create own ActivatedRoute and give it the values from ActivatedRouteSnapshot which knows about 'foo/'
    const foo: ActivatedRoute = new ActivatedRoute();
    console.log(foo);

    // Error: Cannot match any routes
    // I think because there is no route to be relative to when canActivat is called. Router has not yet navigated to '/foo/'
    this.router.navigate(['../foo-child'], {               relativeTo: this.route
    });

    // Errors with infinite loop because '/foo/' has this guard which will then be called again
    //this.router.navigate(['/foo/foo-child']);

    // navigate returns true also. maybe just return that.
    return true;
  }

*为什么不为您可能要问的所有孩子增加警卫。我需要根据应用程序的状态从父路由重定向到许多不同的子路由。我目前正在使用子路线之一从该组件重定向,但这并不能保护子路线由用户直接导航。

1 个答案:

答案 0 :(得分:2)

一种实现此目的的方法可能是使用url参数,在输入父路由时使用canActivateChild和redirectTo子路由。

StackBlitz示例:https://stackblitz.com/edit/angular-redirect-with-params

路由

const appRoutes: Routes = [
  {
    path: 'foo',
    component: FooComponent,
    canActivateChild: [ RedirectionGuard ],
    children: [
      {
        path: '',
        pathMatch: 'full',
        redirectTo: 'foo-child-1'
      },
      {
        path: 'foo-child-1',
        component: FooChildComponent
      },
       {
        path: 'foo-child-2',
        component: FooChildComponent
      }
    ]
  },
];

后卫

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean>|Promise<boolean>|boolean {

    console.log('params:', route.params, route.url);
    if (!route.params.skip) {
      this.router.navigate(['/foo/foo-child-2', { skip: true }], {
        queryParams: { skip: 1 }
      });
    }

    return true;

  }

  canActivateChild(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ) {
    return this.canActivate(route, state);
  }