从angular中的子节点路由到另一个根节点的正确方法是什么?

What is the right way to route to another root node from a child node in angular?

我有一个登录页面和一个延迟加载的模块,其子项构成了应用程序中的大部分页面。下面是 app-routing.module.ts

const routes: Routes = [{
    path: '',
    loadChildren: './main/main.module#MainModule'
  },
  {
    path: '',
    component: LoginLayoutComponent,
    children: [{
      path: 'login',
      component: LoginComponent
    }]
  },
  {
    path: '**',
    component: PageNotFoundComponent
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

现在我有了包含几个子页面的主模块。我们来看看main-routing.module.ts

onst routes: Routes = [{
  path: '',
  canActivate: [AuthGuard],
  component: LayoutComponent,
  children: [{
      path: '',
      redirectTo: 'home',
      pathMatch: 'full'
    },
    {
      path: 'home',
      component: HomeComponent
    },
    {
      path: 'user',
      loadChildren: './user/user.module#UserModule'
    },
    {
      path: 'dashboard',
      loadChildren: './dashboard/dashboard.module#DashboardModule'
    },
    {
      path: '**',
      component: PageNotFoundComponent
    }
  ]
}];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class MainRoutingModule {}

在 RouteGuard 中,如果用户未登录,我们会将他们重定向到 /login

    this.router.navigate(['/login']);

问题是路由器试图在 MainRoutingModule 的路由中找到 path:'login',而 'login' 实际上是 AppRoutingModule 路由的一部分。任何帮助,将不胜感激。

我相信路由器正在您的 app-routing 模块中进行第一个匹配,您指定为 ''。然后加载 children,即 main-routing 模块。由于主路径和登录路径相同 - '' - 路由器永远不会进入第二个匹配项。考虑将登录 parent 路由路径设为 'login' 并将登录 child 路径设为 ''

编辑 1:

路由器似乎仍然匹配主模块路径值中的''。考虑 re-ordering 主模块上方的登录组件 and/or 向主模块的路径添加一个值而不是空 - ''.

顺便说一句,您基本上是一次延迟加载整个应用程序。随着时间的推移,您可能会考虑将所有这些 children 拉出主模块并直接从应用程序路由模块延迟加载它们。 (这也可以解决您的问题,因为您不会在 App Routing 模块中有空的 - '' - 路径)。

当您使用空路径时 - '' - 考虑根据 Angular Route 文档添加 'full'pathMatch 策略,这样您就不会 运行再次陷入这个问题,因为从技术上讲,每个根路径都会匹配一个空的 - '' - 在任何其他后续段之前的段(你在这里面临的同样问题)。

编辑 2:

const routes: Routes = [
  {
    path: 'login',
    component: LoginLayoutComponent,
    children: [{
      path: '',
      pathMatch: 'full',
      component: LoginComponent
    }]
  },
  {
    path: 'main',
    loadChildren: () => import('./main/main.module').then(m => m.MainModule)
  },
  {
    path: '**',
    component: PageNotFoundComponent
  }
];