Angular动态路由出口重复创建组件问题排查求助
我有如下简单路由配置:
const appRoutes: Route[] = [ { path: 'route', outlet: 'outlet', component: TestComponent, } ];
我希望每次点击“create router outlet”按钮时,更新当前应用路由配置,添加一条与现有路由类似但出口名称不同的新路由,并创建name属性为outlet-1的新路由出口:
const appRoutes: Route[] = [ { path: 'route', outlet: 'outlet', component: TestComponent, }, { path: 'route', outlet: 'outlet-1', component: TestComponent, } ];
<router-outlet name="outlet-1"></router-outlet>
导航到该新路由出口时,TestComponent应在对应出口下方渲染:
this.router.navigate([{ outlets: { ['outlet-1']: ['route'] } }]);
我能实现上述功能,但TestComponent会被多次创建:第一次点击按钮→test component constructor.日志出现1次;第二次点击→日志出现2次;第三次点击→日志出现3次,以此类推。理想状态应为每次点击按钮日志仅出现1次,请问问题出在哪里?
问题根源
你每次点击按钮时都会修改原路由数组并调用router.resetConfig()重置路由配置,而Angular在重置路由配置时,会重新匹配当前已激活的所有路由状态(包括之前创建的所有命名出口对应的路由),导致之前所有的TestComponent实例被重新销毁并创建,再加上新出口的实例,最终出现创建次数递增的情况。
另外,你完全不需要重复添加路由配置——Angular允许同一路由规则匹配不同的命名出口,无需为每个新出口新增一条路由。
解决方法
保留初始路由配置,无需动态添加新路由
初始路由配置只需保留一条即可,不需要为每个新出口新增路由项:const appRoutes: Route[] = [ { path: 'route', component: TestComponent, } ];(如果需要指定默认出口,可保留
outlet: 'outlet',不影响其他命名出口的匹配)点击按钮时仅创建新路由出口并导航
点击按钮时,直接生成新的命名出口元素添加到DOM,然后导航到该出口即可,无需修改路由配置:// 生成新出口名称,比如按序号递增 const newOutletName = `outlet-${this.outletCount++}`; // 创建router-outlet元素并添加到DOM(示例代码,根据你的DOM结构调整) const outletEl = document.createElement('router-outlet'); outletEl.setAttribute('name', newOutletName); document.getElementById('outlet-container')?.appendChild(outletEl); // 导航到新出口 this.router.navigate([{ outlets: { [newOutletName]: ['route'] } }]);
这样修改后,每次点击按钮只会创建新的TestComponent实例,不会触发之前实例的重新创建,符合预期效果。
内容的提问来源于stack exchange,提问作者Ravi Teja

