具有路由参数和命名路由器出口的延迟加载模块

Posted

技术标签:

【中文标题】具有路由参数和命名路由器出口的延迟加载模块【英文标题】:Lazy load module with route params and named router outlet 【发布时间】:2019-12-07 06:36:58 【问题描述】:

我有一个路由/组件,它需要一个路由参数并且有一个命名的出口。我想延迟加载一个模块并激活这条路线。这是我的路线:

Profile Module(子模块)Routes:

const routes: Routes = [

  path: ':id', component: ProfileComponent
  children: [
    path: 'list/:id', component: ListComponent, outlet: 'sidebar' ,
    path: 'risk/:id', component: RiskComponent, outlet: 'sidebar' 
  ], 
];

父模块路由

const routes: Routes = [
   path: 'projects/profile',
    loadChildren: './profile/profile.module#ProfileModule' 
 ]

加载路由报错:

错误:无法匹配任何路由。 URL 段:'projects/profile/-3'

当我在子模块中使用空字符串作为路径时,没有错误并且模块加载但组件不加载。我发现 this help 使用延迟加载路由参数,this help 使用延迟加载命名路由器出口,但都没有工作。

我的问题是: 如何延迟加载带有路由参数和命名路由器出口的路由?

--编辑--

这是一个demo app,它显示了我的问题。我创建了 3 条主要路线:一种延迟加载没有命名插座的子模块,一种延迟加载带有命名插座,另一种不使用延迟加载。在 UI 中,指向具有命名出口的路由的链接会产生上述错误。

【问题讨论】:

【参考方案1】:

你似乎有两次component: ProfileComponent。那是你要的吗?这可能会导致路由问题。

此外,对于延迟加载包含它的子模块的模块,在您的父路由中,您还可以这样做:

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

如果您有一个演示应用程序进行诊断,那将会很有帮助。 StackBlitz 示例可以提供更多帮助。

更新:

在你的 app.module.ts 中:

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

在您的 profile.routing.ts 中:

const appRoutes: Routes = [
  
    path: '', 
    pathMatch: 'full',
    component: ProfileComponent,
  ,
  
    path: 'sidebar', component: SidebarComponent,
    children: [
    
     path: ':id',
    component: AdminUserDetailsComponent,
    
    ]
  ,
];

我认为您不需要name="sidebar" in. Make it`,因为您已经在模块中。路径匹配:“完整”:

pathMatch = 'full' 剩余时会导致路由命中, URL匹配的不匹配段是前缀路径

https://angular.io/guide/router#set-up-redirects

最后,您的链接应该导航到完整路径:

  <a [routerLink]="['/profile/sidebar']">Outlet defined and specified doesn't work (ProfileModule)</a>
  <a [routerLink]="['/profile']">With outlet defined but not specified (ProfileModule: '/profile/3')</a>

我从不使用内联参数路由,因为它们难以阅读、导航、计算和调试。

【讨论】:

这是一个demo app 我创建了 StackBlitz。我创建了 3 条主要路线:一条延迟加载没有命名插座的子模块,一条延迟加载带有命名插座,另一条不使用延迟加载。任何帮助将不胜感激。 感谢演示。这很有帮助。请看我上面的更新 非常感谢您的回答。我需要,但是需要命名路由器插座,因为我的实际应用程序在 ProfileComponent 页面上有两个插座。为了简洁起见,我只有一个。这些网点也需要路由参数。经过一些测试,我发现了一些可行的方法。我发布了一个答案。【参考方案2】:

它应该和经典的延迟加载没有什么不同,可能导致问题的原因是路径:':id'在配置文件路由中,尝试将其更改为空path: '',您也可以将:id移动到父路由路径:'projects/profile/:id'

【讨论】:

我尝试将 :id 移至父级,但它不起作用。但是,如果我完全删除 :id,它确实有效,但我的页面没有加载。 (我从上面提供的第一个链接中得到了将 id 添加到子模块路由的想法) 在尝试了一些排列之后,我确实得到了部分工作。将 :id 移至父级后,我发现以下路线有效:localhost:4200/projects/profile/18。但是,命名的路由器插座不起作用。导航到路线:localhost:4200/projects/profile/18/(sidebar:list/18) 会出现上述错误。 我在上面添加了一个示例项目。任何反馈将不胜感激。【参考方案3】:

所以经过反复试验,我找到了答案。我创建了这个实现它的demo。作为说明,我需要多个带有路由参数的路由器插座(演示只包含一个具有一个路由器插座的组件,但我的实际应用程序有两个。因此我需要命名它)

父模块

正如 Thomas Cayne 所提到的,延迟加载模块的链接如下(注意缺少 :id 路由参数。这是因为该路由仅用于延迟加载):

 path: 'profile', loadChildren: () => import('./profile/profile.module').then(m => m.ProfileModule) ,

子模块

子模块中的路由如下:(***路由具有 :id 路由参数,因为它的组件需要使用 :id。在我的例子中,子插座也需要一个 :id。插座使用参数来加载它的数据。)

 const appRoutes: Routes = [
   
   path: 'test/:id', component: ProfileComponent,
   children: [
     path: 'bar/:id', component: SidebarComponent, outlet:'sidebar' 
   ] 
  ,
 ];

父模板

最后,通过延迟加载模块正确路由到具有命名路由器出口和路由参数的组件的 routerLink 如下:

<a [routerLink]="['/', 'profile', 'test', 3,  outlets:  sidebar: ['bar', 3 ]  ]">Working Router outlet and route params</a>

【讨论】:

以上是关于具有路由参数和命名路由器出口的延迟加载模块的主要内容,如果未能解决你的问题,请参考以下文章

Angular 9 嵌套延迟加载模块,带有嵌套路由器出口

没有路由器的角度延迟加载模块

延迟加载模块中的 Angular single-spa 延迟加载路由调用未定义的 webpack 错误

Vue路由器如何在页面加载时获取延迟加载模块的当前路由路径?

如何处理 angular2 延迟加载路由失败

角度 5 中具有相同 URL 的两个不同组件(通过延迟加载在路由器中传递 slug)