Angular 5子路由用loadChildren加载时错误显示在根路由出口
问题分析与解决方案
你的问题核心是路由配置层级错误,导致子路由同时被根router-outlet和Home组件内的router-outlet匹配加载。具体来说,你没有将Home模块作为根路由的子模块通过正确方式引入,反而直接把HomeRoutingModule注册到了AppModule中,这使得Home模块的路由规则和根路由规则合并,导致create这类子路由既会被根路由匹配(直接显示在根出口),又会在访问test/create时被Home的子路由匹配(显示在Home的出口)。
下面是具体的修复步骤:
步骤1:修正根路由配置(app-routing.module.ts)
你需要在根路由中添加加载Home模块的规则,确保Home模块作为根路由的子层级存在,调整后的代码如下:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; export const APP_ROUTES: Routes = [ // 配置加载Home模块,作为根路由的子路由入口 { path: '', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) }, // 通配符路由放在最后,处理未匹配的路径 { path: '**', redirectTo: '', pathMatch: 'full' } ]; @NgModule({ imports: [RouterModule.forRoot(APP_ROUTES)], exports: [RouterModule] }) export class AppRoutingModule { }
步骤2:确保Home路由仅在HomeModule中注册
检查HomeModule的代码,确认HomeRoutingModule只在HomeModule的imports数组中,绝对不要在AppModule中导入HomeRoutingModule:
// home.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { HomeRoutingModule } from './home-routing.module'; import { HomeComponent } from './home.component'; import { DashboardComponent } from './dashboard/dashboard.component'; @NgModule({ declarations: [HomeComponent, DashboardComponent], imports: [ CommonModule, HomeRoutingModule // 仅在这里导入路由模块,隔离路由层级 ], providers: [LoggedUserGuard, AuthGuard] }) export class HomeModule { }
步骤3:验证Home路由的层级配置(home-routing.module.ts)
你的Home路由配置本身逻辑是对的,保持当前结构即可,它会作为Home模块的内部路由规则,由Home组件内的router-outlet负责渲染子路由:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { LoggedUserGuard } from '../guards/logged-user.guard'; import { AuthGuard } from '../guards/auth.guard'; const routes: Routes = [ { path: '', component: HomeComponent, canActivate: [LoggedUserGuard], canActivateChild: [AuthGuard], children: [ { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, { path: 'test', loadChildren: () => import('./test/test.module').then(m => m.TestModule) }, { path: 'dashboard', component: DashboardComponent, data: { breadcrumb: 'Dashboard' } }, { path: 'dummy', loadChildren: () => import('./dummy/dummy.module').then(m => m.DummyModule) } ] } ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class HomeRoutingModule { }
步骤4:确认Test模块的路由配置(test-routing.module.ts)
Test模块的路由配置无需修改,它会作为Home模块的子路由,只能通过/test/create这类层级路径访问:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { TestComponent } from './test.component'; import { ListComponent } from './list/list.component'; import { TestCreateComponent } from './create/test-create.component'; import { TestEditComponent } from './detail/test-edit.component'; const routes: Routes = [ { path: '', component: TestComponent, children: [ { path: '', component: ListComponent, data: { breadcrumb: 'List' } }, { path: 'create', component: TestCreateComponent }, { path: 'detail/:id', component: TestEditComponent } ] } ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class TestRoutingModule { }
修复原理说明
通过在根路由中用loadChildren加载Home模块,我们把Home的路由规则完全隔离在自己的模块层级中:
- 根路由只会匹配到Home模块的入口路径,然后渲染Home组件到根
router-outlet; - Home组件内的
router-outlet负责渲染其内部的子路由(比如Dashboard、Test模块); - Test模块的子路由(如
create)只会作为Test模块的层级路由存在,只能通过/test/create访问,不会再被根路由匹配到/create路径。
内容的提问来源于stack exchange,提问作者crystalthinker
相关产品推荐
相关产品推荐

