Angular 13:重复点击导航按钮后WriteUp组件内容无法正常显示的问题
你的核心问题在于Angular的组件复用策略:当你从dashboard/writeup/show直接点击WriteUp导航按钮时,WriteUpComponent已经处于激活状态,Angular不会重新创建这个组件,所以ngOnInit里的this.router.navigate(['dashboard/writeup/index'])不会再次执行,导致router-outlet区域为空。而切换到Backlog再返回时,WriteUpComponent被销毁后重建,ngOnInit触发,自然就加载了Index组件的gridlist。
下面提供几种实用的解决思路,你可以根据自己的需求选择:
方案1:配置路由默认重定向(最推荐)
直接在路由配置中给writeup路径添加默认重定向规则,当访问dashboard/writeup时自动跳转到index子路由,完全符合Angular路由设计规范:
修改app-routing.module.ts
const routes: Routes = [ ... { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuardGuard], children: [ { path: 'backlog', component: BacklogComponent }, { path: 'writeup', component: WriteUpComponent, children: [ { path: '', redirectTo: 'index', pathMatch: 'full' }, // 添加这行默认重定向 { path: 'index', component: IndexComponent }, { path: 'show', component: ShowComponent } ] }, ] } ];
这样不管是第一次进入WriteUp,还是从show页面返回,都会自动加载Index组件的gridlist,不需要修改任何组件逻辑。
方案2:直接导航到Index子路由(最简单)
修改Navbar中WriteUp按钮的导航目标,直接指向dashboard/writeup/index,跳过根路由的跳转:
修改navbar-component.html
<button (click)="navigate('dashboard/writeup/index')" class="btn btn-outline-info mx-1" type="button">Write-up</button>
这种方式非常直观,点击按钮就强制跳转到gridlist页面,适合不需要保留dashboard/writeup根路由访问需求的场景。
方案3:在WriteUpComponent中监听路由变化
如果需要保留根路由的灵活性,可以在WriteUpComponent中监听路由事件,确保每次进入根路由时自动跳转到Index:
修改writeup-component.ts
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; import { filter, takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; @Component({ selector: 'app-write-up', templateUrl: './write-up.component.html', styleUrls: ['./write-up.component.scss'] }) export class WriteUpComponent implements OnInit, OnDestroy { private destroy$ = new Subject<void>(); constructor(private router: Router) { } ngOnInit(): void { this.checkAndNavigateToIndex(); // 监听路由导航结束事件,每次都检查是否需要跳转 this.router.events.pipe( filter(event => event instanceof NavigationEnd), takeUntil(this.destroy$) ).subscribe(() => { this.checkAndNavigateToIndex(); }); } private checkAndNavigateToIndex(): void { const currentUrl = this.router.url; if (currentUrl === '/dashboard/writeup') { this.router.navigate(['index'], { relativeTo: this.router.routerState.root.children[0] }); } } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }
这个方案可以灵活处理路由变化,同时保持组件的独立性。
内容的提问来源于stack exchange,提问作者Martijn van der Bruggen

