【问题标题】:Angular lazy loaded module failed to navigate to child routesAngular 延迟加载模块无法导航到子路由
【发布时间】:2018-12-22 01:29:25
【问题描述】:

我正在创建一个仪表板应用程序,到目前为止我有两个延迟加载的模块 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]
})

我的app.component.html 有一个<router-outlet></router-outlet>,应该在其中呈现上述路由。

所以这些网址可以正常工作 /auth//admin/

在我的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]
})

这样/admin/ 路由会直接导航到/admin/dashboard/,这也很完美。

在我的admin.component.html 中,我添加了另一个<router-outlet></router-outlet>,它应该在其中呈现AdminModule 路由,所以我可以有一个侧导航栏布局。

问题是,只有 AdminModule 的默认路由 /admin/dashboard 在我尝试导航到任何其他子路由(如 /admin/users//admin/booking/)时完美呈现在第二个 router-outlet 内,应用程序重定向到NotFoundComponent

这是我的问题说明。

【问题讨论】:

    标签: angular routing routes lazy-loading


    【解决方案1】:

    我终于找到了解决办法。

    在您的 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]
        }
    
    )
    

    在您的延迟加载模块路由文件 (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]
    })
    

    现在您的代码应该可以正常工作了

    【讨论】:

    • 这不是打破了“懒惰”——通过在根路由器中引用AdminComponent,您必须在您的AppModule 中导入AdminModule,因此将其捆绑到main.js 中?
    • @Charly 不,它没有。管理模块是要导入到应用程序模块中的。仅导入 Admin 组件。管理组件是 AppModule 的一部分。但是孩子是懒加载的。
    【解决方案2】:

    试试这个

    {
      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 }
          ]
        }
      ]
    }
    

    【讨论】:

      【解决方案3】:

      您定义admin-routing.module.ts 的方式意味着所有子路由都需要在AdminComponent 的模板中包含一个元素。 Angular 会尝试将所有子组件渲染到 AdminComponent。

      我遇到了同样的问题。我没有设法在根路由器插座中呈现延迟加载模块的子路由。我通过以下算法解决了这个问题:

      对于应该在AppComponent 的出口中呈现的延迟加载模块M 的每个子组件c

      • c 创建一个延迟加载模块
      • 在根目录下的 app-routing.module 中定义一个路由,其路径指向延迟加载的模块c
      • M的路由声明中删除路由

      对于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]
      })
      

      这个解决方案有几个缺点:

      1. 您无法按预期封装模块,即丢失父子语义
      2. 您不能简单地重用来自父路由的反序列化模块 - 以防您有深度嵌套

      所以它并不理想,但它确实有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 2023-01-19
        • 1970-01-01
        • 2019-04-19
        • 2017-08-21
        相关资源
        最近更新 更多