Angular模块路由异常:访问/customers无法加载对应模块
Angular多模块路由加载异常问题解决
问题场景
开发多模块管理系统,模块结构如下:
AppModule ├── login-module └── main-module ├── dashboard-module └── customers-module
- 登录成功后从login-module重定向至main-module
- 从
http://localhost:4200/dashboard切换到http://localhost:4200/customers时,customers模块无法加载 - 直接访问
http://localhost:4200/customers/customers则能正常加载
相关代码片段
1. app-component.html
<router-outlet></router-outlet>
2. app-routing.module.ts
import { RouterModule, Routes } from '@angular/router'; import { AuthGuard } from './guards/AuthGuard/auth.guard'; const routes: Routes = [ { path: "", redirectTo: '/dashboard', pathMatch: "full" }, { path: "dashboard", loadChildren: () => import('./modules/main/main.module').then(m => m.MainModule) }, { path: "customers", loadChildren: () => import('./modules/main/main.module').then(m => m.MainModule) }, { path: 'login', loadChildren: () => import('./modules/login/login.module').then(m => m.LoginModule), }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
3. main-routing.module.ts
import { RouterModule, Routes } from '@angular/router'; import { AuthGuard } from 'src/app/guards/AuthGuard/auth.guard'; import { MainComponent } from './components/main/main.component'; const routes: Routes = [ { path: '', component: MainComponent, loadChildren: () => import('../dashboard/dashboard.module').then(m => m.DashboardModule), canActivate: [AuthGuard] }, { path: 'dashboard', component: MainComponent, loadChildren: () => import('../dashboard/dashboard.module').then(m => m.DashboardModule), canActivate: [AuthGuard] }, { path: 'customers', component: MainComponent, loadChildren: () => import('../customers/customers.module').then(m => m.CustomersModule), canActivate: [AuthGuard] }, ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class MainRoutingModule { }
4. main.component.html
<div class="wrapper default-theme" [ngClass]="getClasses()"> <app-navbar></app-navbar> <main> <app-sidebar></app-sidebar> <div class="pages container-fluid pt-4 pb-4 pl-4 pr-4"> <router-outlet></router-outlet> <hr> <app-footer></app-footer> </div> <div class="overlay" (click)="toggleSidebar()"></div> </main> </div>
问题原因
- 在
app-routing.module.ts中,/dashboard和/customers都指向加载MainModule - 当访问
/customers时,进入MainModule的路由匹配逻辑,此时匹配的是**空路径(path: '')**的路由规则,该规则加载的是DashboardModule而非CustomersModule - 而访问
/customers/customers时,MainModule中的path: 'customers'规则被匹配,正确加载CustomersModule,因此可以正常工作
解决方案
方案一:优化路由层级(推荐)
调整路由结构,让MainModule作为父容器,内部承载dashboard和customers子路由,结构更清晰:
修改app-routing.module.ts
import { RouterModule, Routes } from '@angular/router'; import { AuthGuard } from './guards/AuthGuard/auth.guard'; const routes: Routes = [ { path: "", redirectTo: '/main/dashboard', pathMatch: "full" }, { path: "main", loadChildren: () => import('./modules/main/main.module').then(m => m.MainModule), canActivate: [AuthGuard] }, { path: 'login', loadChildren: () => import('./modules/login/login.module').then(m => m.LoginModule), }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
修改main-routing.module.ts
import { RouterModule, Routes } from '@angular/router'; import { AuthGuard } from 'src/app/guards/AuthGuard/auth.guard'; import { MainComponent } from './components/main/main.component'; const routes: Routes = [ { path: '', component: MainComponent, children: [ { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, { path: 'dashboard', loadChildren: () => import('../dashboard/dashboard.module').then(m => m.DashboardModule) }, { path: 'customers', loadChildren: () => import('../customers/customers.module').then(m => m.CustomersModule) } ], canActivate: [AuthGuard] } ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class MainRoutingModule { }
此时访问/main/dashboard和/main/customers即可正常加载对应模块。
方案二:保留根路径直接访问
如果需要保持/dashboard和/customers的根路径访问方式,可调整路由配置,让根路径直接关联对应子模块,同时将MainComponent作为布局容器:
修改app-routing.module.ts
import { RouterModule, Routes } from '@angular/router'; import { AuthGuard } from './guards/AuthGuard/auth.guard'; import { MainComponent } from './modules/main/components/main/main.component'; const routes: Routes = [ { path: "", redirectTo: '/dashboard', pathMatch: "full" }, { path: '', component: MainComponent, canActivate: [AuthGuard], children: [ { path: 'dashboard', loadChildren: () => import('./modules/dashboard/dashboard.module').then(m => m.DashboardModule) }, { path: 'customers', loadChildren: () => import('./modules/customers/customers.module').then(m => m.CustomersModule) } ] }, { path: 'login', loadChildren: () => import('./modules/login/login.module').then(m => m.LoginModule), }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
修改main-routing.module.ts(可删除,或保留为空路由模块)
此时访问/dashboard和/customers会直接加载MainComponent布局,并在其内部router-outlet中加载对应子模块,无需额外嵌套路径。
内容的提问来源于stack exchange,提问作者Snake_Eyes
相关产品推荐
相关产品推荐

