【问题标题】:Angular 8 lazy loading with child routes带有子路由的Angular 8延迟加载
【发布时间】:2019-07-28 19:05:33
【问题描述】:

我正在编写一个 Angular 8 应用程序,我正在尝试延迟加载一些模块。但是,当页面加载时,我收到此错误:

错误:组件 ProfileComponent 不是任何 NgModule 或 模块尚未导入到您的模块中。

具体来说,我希望在命中路由并加载组件时加载模块。问题是组件是模块的一部分。

这是子模块的代码,其中定义了组件:

@NgModule({
  imports: [],
  declarations: [
    ...
    ProfileComponent
  ],
  exports: [
    ...
    ProfileComponent
  ]
 })
 export class ProfileModule { }

这是试图动态加载子模块的父模块中的路由定义:

const routes: Routes = [
  {
   path: 'projects/profile/:id', component: ProfileComponent,  
     loadChildren: () => {
       return import('./profile/profile.module').then(m => m.ProfileModule);
     },
     children: [
       { path: 'list/:id', component: ListComponent, outlet: 'sidebar' },
       { path: 'risk/:id', component: RiskComponent, outlet: 'sidebar' },
       ...
   ]
 }

有没有办法在导航时加载组件和模块?我尝试将有问题的 ProfileComponent 移动到父模块中,但是当我导航到页面时,它希望它的所有子组件都存在(这与延迟加载相反)。我可以创建一个不使用子组件的登录页面,我可以在其中单击以重定向到动态加载子模块的路由,但我宁愿不向应用程序添加另一层单击。

【问题讨论】:

  • 你的父模块不应该直接列出子模块,它应该只使用loadchildren。然后为您的子模块提供自己的路由文件,以将请求转发到其组件。 ;毕竟,只有当你的父级没有对子模块内容的引用时,延迟加载才是延迟加载。而且你也不需要导出组件。

标签: angular angular-router


【解决方案1】:

为什么不在父模块中使用

const routes: Routes [{path:'projects/profile/:id', loadchildren: './profile/profile.module#ProfileModule']

然后在子模块中

const subRoutes: Routes .....
@NgModule({
imports: [RouterModule.forChild(subRoutes)]
exports: [RouterModule]

更多信息您可以查看Angular Routing & Navigation => Milestone 3: Heroes feature

希望这会有所帮助;-)

【讨论】:

  • 我现在收到错误:错误:无法匹配任何路由。 URL 段:'projects/profile/18'。我四处搜索,发现使用延迟加载的命名路由器出口存在问题。建议使用具有顶级路由的非空路径。我尝试了不同的排列,但无法摆脱错误。你能用路由参数和命名的路由器出口详细说明子模块中的路由是什么样的吗?
【解决方案2】:

应用的结构:

├── parent.module.ts/
│   ├── profile.module.ts/
│       └──profile.component.ts/
  • 如果配置文件模块尚未加载,则配置文件组件在父模块的上下文中不存在,因此您收到错误消息“模块尚未导入您的模块”。

如果我没有误解你的问题,你应该像这样在 ProfileModule 中声明另一组路由:

ProfileModule(非父模块)

const routes: Routes = [
   { path: '', component: ProfileComponent }, // /projects/profile/1
   { path: 'list/:id', component: ListComponent, outlet: 'sidebar' }, // /projects/profile/1/list/15 
   { path: 'risk/:id', component: RiskComponent, outlet: 'sidebar' } ///projects/profile/1/risk/20
]

//and then import it into your parent module RouterModule

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

ParentModule - 移除 ProfileComponent

const routes: Routes = [
  {
   path: 'projects/profile/:id', loadChildren: () => import('./profile/profile.module').then(m => m.ProfileModule)
  }
]

在 Angular 8 中使用 import 关键字进行延迟加载是正确的,因为字符串语法 has been deprecated 但您可以通过删除 return 关键字来减少冗长。

【讨论】:

  • 还有一个问题。您在父路由模块中定义的子路由的子组件仅在子模块中定义。它们在父级中不可用。
  • 在这种情况下,您可以将它们作为直接路由转移到您的子模块中(您指的是配置文件模块吗?)。此外,这在很大程度上取决于您希望路线的外观。 *我已经编辑了我的答案
  • 我收到一条错误消息,提示找不到路线。我认为这是一个复杂的问题,因为我同时使用路由参数和命名路由器出口。我找到了thisthis,但都没有帮助。如果我取出路由参数并为子模块中的顶级路由使用空字符串,我可以加载模块,但页面不加载
  • 这是您正在寻找的行为吗? stackblitz.com/edit/angular-zbgnpq 我已经创建了这个 stackblitz,它似乎工作正常。我可以访问/profile/2/risk/1/profile/2/list/1。看看它并尝试将其与您的上下文相匹配?
  • 感谢您的示例。我无法让子路由加载。我确实找到了位于here 的答案。
猜你喜欢
  • 2019-01-13
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 2017-05-17
  • 1970-01-01
相关资源
最近更新 更多