You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:25:18