Angular Router模块路由构建二级导航菜单遇NG04013报错求助
解决Angular多Router Outlet重复激活报错(NG04013)
核心原因
通过路由解析器动态加载子菜单路由时,重复触发导航会尝试再次激活已处于激活状态的router-outlet,Angular不允许重复激活同一出口,从而抛出NG04013错误。
具体修复方案
1. 调整路由配置,删除重复出口绑定
子模块路由中,避免重复指定outlet属性,改为通过父路由的解析器注入菜单数据,让子路由复用已激活的出口:
// 子模块路由示例(如dashboard-routing.module.ts) const routes: Routes = [ { path: '', component: DashboardComponent, children: [ { path: 'overview', component: OverviewComponent }, { path: 'analytics', component: AnalyticsComponent } ] } ];
2. 优化导航组件的路由触发逻辑
在导航组件中,先判断目标出口是否已激活,已激活则仅更新子路由,而非重新触发完整导航:
navigateToSubMenu(item: MenuItem) { const currentRoute = this.router.routerState.root.firstChild; const subOutletActivated = currentRoute?.children?.some(child => child.outlet === 'submenu'); if (subOutletActivated) { // 复用现有出口,仅更新内容路由 this.router.navigate([{ outlets: { content: [item.path] } }], { relativeTo: currentRoute }); } else { // 首次激活出口,加载子菜单和对应内容 this.router.navigate([ { outlets: { submenu: [item.module], content: [item.path] } } ], { relativeTo: currentRoute }); } }
3. 给路由解析器添加缓存逻辑
避免每次导航时重复注入相同菜单数据,减少不必要的路由重建:
@Injectable() export class MenuResolver implements Resolve<MenuItem[]> { private cache = new Map<string, MenuItem[]>(); resolve(route: ActivatedRouteSnapshot): Observable<MenuItem[]> { const module = route.paramMap.get('module'); if (module && this.cache.has(module)) { return of(this.cache.get(module)!); } return this.menuService.getMenu(module).pipe( tap(menu => module && this.cache.set(module, menu)) ); } }
4. 导航时添加skipLocationChange选项
防止重复路由记录触发出口重复激活:
this.router.navigate(/* 路由配置 */, { relativeTo: currentRoute, skipLocationChange: true });
验证修复
完成上述修改后,多次点击主导航和子菜单,三个router-outlet可正常切换复用,不会再触发NG04013错误。
内容的提问来源于stack exchange,提问作者shoop
相关产品推荐
相关产品推荐

