首页 > 解决方案 > Angular Router - 延迟加载的模块无法将 URL 与参数匹配

问题描述

当我的整个应用程序急切加载时,我以前有以下工作代码

// previous code
const homeRoutes: Routes = [{
  path: '',
  component: HomeComponent,
  canActivate: [AuthGuard],
  children: [
    { path: 'profile', component: ProfileComponent },
    { path: 'user/:userId', component: ProfileComponent, pathMatch: 'full'},
    // others not shown
  ]
}];

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

页面与/profile页面是相同的组件/user/{id}——但布局略有不同,因此我对它们的处理方式略有不同。

从那以后,我从 Angular 7 升级到 Angular 8,并实现了延迟加载,它可以在我的应用程序中的任何地方工作,除了这里。我认为这是因为这条路线不像其他路线有一个参数?

这是我的新路由代码

const homeRoutes: Routes = [{
  path: '',
  component: HomeComponent,
  canActivate: [AuthGuard],
  children: [
    { path: 'user/:id', loadChildren: () => import('../profile/profile.module').then(mod => mod.ProfileModule) },
    { path: 'profile', loadChildren: () => import('../profile/profile.module').then(mod => mod.ProfileModule) },
    // others not shown
  ]
}];

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

配置文件模块具有以下代码:

@NgModule({
  imports: [
    SharedModule,
    CommonModule,
    RouterModule.forChild([
      { path: '', component: ProfileComponent }
    ])
  ],
  declarations: [
    ProfileComponent, // others not shown
  ],
  entryComponents: [] // contents not shown
})
export class ProfileModule { }

问题是当我尝试导航到/user/5cd466b3cdd9b31594bad5d7我收到以下错误:

ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'user/5cd466b3cdd9b31594bad5d7'

这里发生了什么?

编辑:我使配置文件组件非延迟加载(并将其从其模块中删除,将其放在以前的位置 - 主模块)。我还使路由到它的组件之一非延迟加载(并将其从其模块中删除,将其放置在以前的位置 - 主模块)。然后它起作用了。当我使链接到配置文件的组件再次延迟加载时,它停止工作。因此,从延迟加载的组件内部调用 this.router.navigate() 似乎会导致问题。不过,我不知道为什么。

标签: angularangular2-routingangular-routing

解决方案


为了能够使用延迟加载模块中的参数访问路由必须在模块和延迟加载模块中定义路由模式。

因此,您的代码变为:

const homeRoutes: Routes = [{
  path: '',
  component: HomeComponent,
  canActivate: [AuthGuard],
  children: [
    // Declaring this is IMPORTANT!
    { path: 'user', loadChildren: () => import('../user/user.module').then(mod => mod.UserModule) },
    { path: 'user/:id', loadChildren: () => import('../user/user.module').then(mod => mod.UserModule) },
    { path: 'profile', loadChildren: () => import('../profile/profile.module').then(mod => mod.ProfileModule) },
    // others not shown
  ]
}];

然后,在您的user-routing.module.ts

const routes: Routes = [
   /* ... */
  { path: ':id', component: UserComponent },
 /* ... */
];

这是一个应用上述想法的 StackBlitz 示例。


推荐阅读