简体   繁体   English

Angular延迟加载模块无法导航到子路由

[英]Angular lazy loaded module failed to navigate to child routes

I'm creating a dashboard app and so far I have two lazy loaded modules AuthModule and AdminModule My app-routing-module.ts looks like this 我正在创建一个仪表板应用程序,到目前为止,我有两个延迟加载的模块AuthModuleAdminModule我的app-routing-module.ts看起来像这样

const routes: Routes = [
    {
     path: '',
     loadChildren: './auth/auth.module#AuthModule'
    },
    {
     path: 'admin',
     loadChildren: './admin/admin.module#AdminModule',
     canActivate: [AuthGuardService]
    },
    {
      path: '**',
      component: NotFoundComponent
    }
];

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

My app.component.html has a <router-outlet></router-outlet> that should render the above routes inside it. 我的app.component.html有一个<router-outlet></router-outlet> ,它应该在其中呈现上述路由。

so these urls are working /auth/ and /admin/ perfectly 所以这些网址正在工作/auth//admin/ perfect

In my admin-routing.module.ts I have the following routes 在我的admin-routing.module.ts我有以下路由

const routes: Routes = [
  {
    path: '',
    component: AdminComponent,
    children: [
      {path: '', pathMatch: 'full', redirectTo: 'dashboard'},
      {path: 'dashboard', component: DashboardComponent },
      {path: 'users', component: UsersComponent },
      {path: 'reports', component: ReportsComponent },
      {path: 'booking', component: BookingComponent }
    ]
  }
];

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

so that /admin/ route directly navigates to /admin/dashboard/ which is also working perfectly. 这样/admin/ route直接导航到/admin/dashboard/也正常工作。

In my admin.component.html I added another <router-outlet></router-outlet> that should renders AdminModule routes inside it, so I can have a sidenav bar layout. 在我的admin.component.html我添加了另一个<router-outlet></router-outlet> ,它应该在其中呈现AdminModule路由,所以我可以有一个sidenav栏布局。

The problem is that only the default route for AdminModule which is /admin/dashboard renders perfectly inside the second router-outlet whenever I try to navigate to any other child route like /admin/users/ or /admin/booking/ the app redirects to NotFoundComponent 问题是每当我尝试导航到/admin/users//admin/booking/ app重定向到的任何其他子路由时,只有/admin/dashboard AdminModule默认路由完全呈现在第二个router-outletNotFoundComponent

Here's my problem illustrated. 这是我的问题说明。 管理模块“仪表板”的默认子路由 试图打另一条儿童路线

try this 尝试这个

{
  path: '',
  component: AdminComponent,
  children: [
    {path: '', pathMatch: 'full', redirectTo: 'dashboard'},
    {
      path: 'dashboard', 
      component: DashboardComponent,
      children: [
        {path: 'users', component: UsersComponent },
        {path: 'reports', component: ReportsComponent },
        {path: 'booking', component: BookingComponent }
      ]
    }
  ]
}

The way you define admin-routing.module.ts means that all child routes expect an element inside the AdminComponent's template. 定义admin-routing.module.ts方式意味着所有子路由都期望AdminComponent模板中的元素。 Angular will try to render all children into the AdminComponent. Angular将尝试将所有子项呈现为AdminComponent。

I had the same problem. 我有同样的问题。 I didn't manage to render the child routes of a lazy loaded module inside the root router-outlet. 我没有设法在根路由器插座内渲染延迟加载模块的子路由。 I solved this issue by the following algorithm: 我通过以下算法解决了这个问题:

For each child Component c of a lazy loaded module M that should be rendered in the AppComponent 's outlet: 对于应该在AppComponent的插座中呈现的延迟加载模块M每个子组件c

  • create a lazy loaded module for c c创建一个延迟加载的模块
  • define a route in your app-routing.module under root with the path needed that points to the lazy loaded module c 在root下的app-routing.module中定义一条路由,指向延迟加载的模块c所需的路径
  • remove the route from M 's routing declaration M的路由声明中删除路由

For admin/users this could look something like this: 对于admin/users这看起来像这样:

app-routing-module.ts

const routes: Routes = [
    {
     path: '',
     loadChildren: './auth/auth.module#AuthModule'
    },
    {
     path: 'admin',
     loadChildren: './admin/admin.module#AdminModule',
     canActivate: [AuthGuardService]
    },
    {
     path: 'admin/users',
     loadChildren: './admin/users/admin-users.module#AdminUsersModule',
     canActivate: [AuthGuardService]
    },
    {
      path: '**',
      component: NotFoundComponent
    }
];

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

This solution has a couple of drawbacks: 这个解决方案有几个缺点:

  1. you cannot encapsulate your modules as expected, ie the parent-child semantics gets lost 您无法按预期封装模块,即父子语义丢失
  2. you cannot simply reuse deserialized modules from parent routes - in case you have deep nesting 您不能简单地从父路由重用反序列化模块 - 以防您有深度嵌套

So it's not ideal, but it works. 所以它不理想,但它的工作原理。

I finally figured out the solution. 我终于找到了解决方案。

In your app.module file change the code to look like this: 在app.module文件中,将代码更改为如下所示:

   const routes: Routes = [
        {
         path: '',
         component: AuthComponent, //<--- Add this
         loadChildren: './auth/auth.module#AuthModule'
        },
        {
         path: 'admin',
         component: AdminComponent, //<--- Add this
         loadChildren: './admin/admin.module#AdminModule',
         canActivate: [AuthGuardService]
        },
        {
          path: '**',
          component: NotFoundComponent
        }
    ];

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

)

In your lazy-loaded module routing file ( admin-routing.module.ts ) change the code to look like this: 在延迟加载的模块路由文件( admin-routing.module.ts )中,将代码更改为如下所示:

const routes: Routes = [

      {path: '', pathMatch: 'full', redirectTo: 'dashboard'},
      {path: 'dashboard', component: DashboardComponent },
      {path: 'users', component: UsersComponent },
      {path: 'reports', component: ReportsComponent },
      {path: 'booking', component: BookingComponent }

];

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

Now your code should work as expected 现在您的代码应该按预期工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM