如何将Angular 15之前的路由守卫转为函数式并注入依赖?
Angular 类式路由守卫转函数式守卫的依赖注入问题
你给出的函数式守卫写法不是正确的依赖注入方式,Angular函数式守卫的依赖不能直接作为函数参数声明,需要通过inject()函数在内部获取。
原类式守卫代码
@Injectable({ providedIn: 'root' }) export class TopicGuardService implements CanActivate { constructor(private router: Router) { } canActivate(route: ActivatedRouteSnapshot): boolean { const topicStore: EStore<Topic> = route.data[TOPIC_STORE_KEY] const id = route.paramMap.get("topic") const topic = topicStore.findOneByID(id || '') if (topic) { return true } this.router.navigate(['/404']) return false } }
正确的函数式守卫实现
函数式守卫需要遵循CanActivateFn的类型签名,仅接收ActivatedRouteSnapshot和可选的RouterStateSnapshot作为参数,依赖通过@angular/core提供的inject()函数注入:
import { inject } from '@angular/core'; import { Router, ActivatedRouteSnapshot, CanActivateFn } from '@angular/router'; // 定义符合CanActivateFn类型的函数式守卫 export const topicGuard: CanActivateFn = (route: ActivatedRouteSnapshot) => { // 用inject()获取Router依赖 const router = inject(Router); const topicStore: EStore<Topic> = route.data[TOPIC_STORE_KEY]; const id = route.paramMap.get("topic"); const topic = topicStore.findOneByID(id || ''); if (topic) { return true; } router.navigate(['/404']); return false; };
关键说明
- Angular函数式守卫的函数签名是固定的,不能自定义添加依赖参数,否则Angular无法自动注入对应实例,运行时会抛出参数缺失的错误。
inject()函数是Angular专为注入上下文(如函数式守卫、管道、独立组件等)设计的依赖注入工具,必须在注入上下文内调用。
内容的提问来源于stack exchange,提问作者Ole
相关产品推荐
相关产品推荐

