当前位置: 首页 > article >正文

由路由守卫引发的Angular DI inject思考

在我修改以前模块的时候,发现路由守卫中的CanActivate已经标记废弃了,现在官网中推荐的是一种模版代码更少的写法:

export const yourGuard: CanActivateFn = (
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
) => {
   // your  logic goes here
}

秉承及时更新代码的原则,我立即对该模块中的路由守卫代码进行了更改,但在修改时遇到了一个问题,即判断逻辑依赖于其他注入,这没有constructor你让我很难办啊 。于是我只好再探官网,发现可以使用 inject 来引用其他依赖项(例: const router = inject(Router) )。
那么这个inject是什么东东呢?

众所周知,在 Angular 中的组件/指令/管道中如果需要使用某个服务,必须通过构造函数参数注入才可使用。

import { Component } from '@angular/core';
import { Injectable } from '@angular/core';
​
@Injectable()
export class HeroService {
  constructor() {}
}
​
@Component({
  selector: 'app-inject',
  template: ``,
  standalone: true,
  providers: [HeroService],
})
export class InjectComponent {
  constructor(private heroService: HeroService) {}
}

如果创建的服务没有通过@Injectable注解进行依赖注入,那么就需要创建一个InjectionToken,此外还需要使用@Inject()注解来在构造函数中引用该依赖项

import { Component, Inject } from '@angular/core';
import { InjectionToken } from '@angular/core';export const InjectToken = new InjectionToken<InjectToken>(
  'Hero_Inject_Token'
);export class HeroService {
  constructor() {}
}
​
@Component({
  selector: 'app-inject',
  template: ``,
  standalone: true,
  providers: [
    {
      provide: InjectToken,
      useClass: HeroService,
    },
  ],
})
export class InjectComponent {
  constructor(
    @Inject(InjectToken) private heroService: HeroService
  ) {}
}

回顾完DI的基础知识,再来看一下官方是怎样解释的

inject可以在以下四种情况使用
在为 Provider 的 @ Injectable useFactory 的工厂函数中
在为 InjectionToken 指定的 factory 函数中。

export const NameToken = new InjectionToken<string>('NAME_TOKEN');
​
@Injectable()
export class HeroService {
  name = 'hero';
  constructor() {}
}
​
@Injectable()
export class SecretHeroService {
  name = 'secretHero';
  constructor() {}
}providers: [
  SecretHeroService,
  //在为  InjectionToken  指定的  factory  函数中
  {
    provide: NameToken,
    useFactory: () => {
      return inject(HeroService).name;
    },
  },
  //在为Provider的Injectable useFactory的工厂函数中
  {
    provide: HeroService,
    useFactory: () => {
      return inject(SecretHeroService);
    },
  },
],

由 DI 系统实例化的类的构造(通过 constructor ),例如 @ Injectable 或 @ Component 。

constructor() {
    const service = inject(HeroService);
    const heroName = service.name
}

在此类类的字段的初始化器中。

 name = inject(HeroService).name;

我们可以拿它干啥?

可以更轻松地在组件之间共享依赖项,并减少对父组件的依赖性。例如,在父组件中使用多个服务时,子组件可以使用 angular inject 注入这些服务,就可以不必手动注入每个服务。
可以让更加方便地在子组件中注入父组件中使用的服务,而不必关心父组件到底使用了哪些注入项。这样的设计可以提高代码的可重用性,使得子组件的实现更加独立,不会被父组件的变化所影响
未使用inject

@Injectable({  providedIn: 'root'})
export class childService extends ParentService {
  constructor(public http: HttpClient) {
    super(http);
  }
}
​
@Injectable({  providedIn: 'root'})
export class ParentService {
  constructor(public http: HttpClient) {}
}

使用inject

@Injectable({ providedIn: 'root' })
export class childService extends ParentService {
  constructor() {
    super();
  }
}
​
@Injectable({ providedIn: 'root' })
export class ParentService {
  http = inject(HttpClient);
  constructor() {}
}

http://www.kler.cn/a/17615.html

相关文章:

  • FluentUI使用
  • change buffer:到底应该选择普通索引还是唯一索引
  • SpringCloud学习笔记
  • Microsoft 365 Exchange如何设置可信发件IP白名单
  • python: postgreSQL using psycopg2 or psycopg
  • 车载空气净化器语音芯片方案
  • 【数据结构】二叉搜索树
  • TortoiseGit提示No supported authentication methods available异常
  • tab widget用法
  • 第一章(四):Django框架的模板(DTL):变量、标签、模板过滤器、模板继承、配置模板文件(staticfiles)
  • B树(B-tree、B-树)理论详解
  • SPSS如何进行方差分析之案例实训?
  • 蓝牙耳机哪款性价比高一些?2023年性价比最高的蓝牙耳机推荐
  • 一、spring Cloud Alibaba概述
  • No.046<软考>《(高项)备考大全》【专项2】《案例分析 - 计算题(中)》
  • API接口的应用
  • 高性能定时器--时间轮/多级时间轮
  • 用于无线传感器网络路由的改进leach协议(Matlab代码实现)
  • 06_Uboot顶层Makefile分析_前期所做内容
  • C++之异常处理
  • 国民技术N32G430开发笔记(15)- IAP升级 树莓派串口发送数据
  • 如何搭建chatGPT4.0模型-国内如何用chatGPT4.0
  • C语言将汉字保存到文件中
  • 如何显示文件夹的后缀和隐藏文件
  • 一分钟学会Flask框架的安装与快速使用
  • 诺派克ROPEX热封控制器维修RES-407/RES-406