Angular 依赖注入 - 在自定义 Rxjs 操作符中注入服务

Angular 是一个固执己见的框架。看到它如何向开发人员灵活性转变并日益强大,真是令人兴奋。我相信对于 Angular 爱好者来说这是一个快乐的时代。

依赖注入和 RxJS — 在我看来,这两个强大的功能让 Angular 变得独特而灵活。RxJS 自定义运算符是将复杂逻辑组合成可重用函数的好方法。

最近我遇到了一个用例,我需要创建一个自定义 RxJS 操作符,它使用服务来实现一些复杂的用例。

您可以使用“inject”方法访问所需的服务实例,但必须在依赖注入上下文中使用inject。为此,Rxjs操作符可以注册为“InjectionToken”,使用“useFactory”函数实例化其值。由于“u​​seFactory”是注入上下文,因此可以使用inject方法毫无问题地注入服务。

让我们看看如何在 rxjs 自定义操作符中注入下面的服务。

// Service
@Injectable({
  providedIn: 'root',
})
export class Multiplier {
  public transfrom(val: number) {
    return val * 2;
  }
}

下面的自定义 RxJS 运算符使用 Multiplier 服务简单地将给定值乘以 2。

import { inject, InjectionToken } from '@angular/core';
import { Multiplier } from '../services/multiplier';
import { map, OperatorFunction, pipe } from 'rxjs';

export const MULTIPLIER_OPERATOR: InjectionToken>
  = new InjectionToken('Multipler operator', {
    factory(): OperatorFunction {
      const multipler = inject(Multiplier); // injected Multipler service
      return pipe(map((x: number) => multipler.transfrom(x)));
    },
  });

现在可以使用 `@Inject` 装饰器在组件内使用自定义操作符。

import { Component, Inject } from '@angular/core';
import { BehaviorSubject, Observable, of, OperatorFunction } from 'rxjs';
import { MULTIPLIER_OPERATOR } from './rxjs-operators/custom';
import { CommonModule } from '@angular/common';

export class App {
  private _count = 1;
  public base = new BehaviorSubject(this._count);
  public val = new Observable();

  constructor(
    @Inject(MULTIPLIER_OPERATOR) // injected custom operator
    private multiplier: OperatorFunction) {
      this.val = this.base.pipe(this.multiplier); // used rxjs operator
  }

  .....
}

还有其他几种方法可以实现相同的用例,例如创建单独的服务和返回自定义运算符的方法。但我喜欢 InjectionToken 方法,因为它具有自包含性。即使引入信号,RxJS 在不久的将来也不会消失,因此值得尝试。

您可以在此处查看完整的工作示例。

祝你编码愉快...🎉