如何阻止Angular路由不符合条件时子组件初始化执行?
这个问题其实是因为组件的初始化时机晚于路由激活的时机——当你访问/parent/string/child时,Angular会先激活父路由和子路由,然后才会执行父组件的ngOnInit,这时候子组件的ngOnInit已经跑完了,重定向的动作根本拦不住它。
想要在不使用服务的前提下解决这个问题,最简洁的方式就是用路由守卫,把参数校验的逻辑提前到路由激活之前执行,这样不符合规则的请求会直接被拦截,连组件初始化的机会都没有。
1. 创建一个路由守卫
我们可以实现CanActivate守卫,它会在进入父路由(包括所有子路由)之前触发校验:
import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class ParentIdGuard implements CanActivate { readonly NUMBER_REGEX = /^\+?\d+$/; constructor(private router: Router) {} canActivate(route: ActivatedRouteSnapshot): boolean | UrlTree { const id = route.paramMap.get('id'); // 校验id格式,符合就允许进入路由 if (id && this.NUMBER_REGEX.test(id)) { return true; } // 不符合就直接跳转到404页面 return this.router.createUrlTree(['/not-found']); } }
2. 在路由配置中添加守卫
把这个守卫绑定到父路由上,这样所有访问父路由及其子路由的请求都会先经过它的校验:
const routes: Routes = [ { path: 'parent/:id', component: ParentComponent, canActivate: [ParentIdGuard], // 绑定守卫 children: [ { path: 'child', component: ChildComponent } ] } ];
为什么这个方案有效?
路由守卫的执行时机是在路由激活、组件初始化之前,当你访问/parent/string/child时,Angular会先调用ParentIdGuard的canActivate方法:
- 如果id格式正确,允许进入路由,父组件和子组件正常初始化
- 如果id格式错误,直接跳转到
/not-found,父组件和子组件都不会被初始化,自然不会执行它们的ngOnInit
这个方案完全满足你的需求:不需要组件间传值的服务,逻辑集中在守卫里,代码简洁且符合Angular的最佳实践。
内容的提问来源于stack exchange,提问作者Ara Yeressian
相关产品推荐
相关产品推荐

