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

能否在非组件/指令类中使用takeUntilDestroyed?报NG0203错误

非组件/指令类中使用takeUntilDestroyed的解决方案

你遇到的NG0203错误,核心原因是inject()必须在Angular的注入上下文(比如组件/服务的构造函数、工厂函数等)中调用,而非组件/指令类默认不在这个上下文里,直接调用inject(DestroyRef)会失败。以下是两种可行的解决方式:

方案一:将类转为可注入服务(推荐)

把MyTestClass标记为@Injectable,让Angular的依赖注入系统管理它的实例,这样inject()就能正常获取DestroyRef:

import { Injectable, DestroyRef, inject } from '@angular/core';
import { OverlayRef } from '@angular/cdk/overlay';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

@Injectable({ providedIn: 'root' }) // 可根据需求指定注入范围
export class MyTestClass {
  private destroyRef = inject(DestroyRef);

  constructor(public overlay: OverlayRef) {
    this.overlay
      .backdropClick()
      .pipe(takeUntilDestroyed(this.destroyRef)) // 显式传入destroyRef,或省略(Angular自动关联上下文)
      .subscribe(() => {
        // 你的业务逻辑
      });
  }
}

使用时,通过构造函数注入MyTestClass,而非手动new:

// 在组件或其他服务中
constructor(private myTestClass: MyTestClass) {}

方案二:手动传入DestroyRef或注入上下文

如果不想将类转为服务,可从外部注入上下文(比如组件、服务)中获取DestroyRef并传入,或通过Injector手动创建注入上下文:

方式1:直接传入DestroyRef

// 修改MyTestClass,接收外部传入的DestroyRef
export class MyTestClass {
  constructor(
    public overlay: OverlayRef,
    private destroyRef: DestroyRef
  ) {
    this.overlay
      .backdropClick()
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(() => {
        // 你的业务逻辑
      });
  }
}

// 在组件中创建实例时传入DestroyRef
import { Component, DestroyRef, inject } from '@angular/core';
import { Overlay } from '@angular/cdk/overlay';

@Component({...})
export class MyComponent {
  private destroyRef = inject(DestroyRef);
  private overlay = inject(Overlay);

  constructor() {
    const overlayRef = this.overlay.create();
    const testInstance = new MyTestClass(overlayRef, this.destroyRef);
  }
}

方式2:用runInInjectionContext手动创建上下文

如果需要在类内部调用inject(),可传入Injector并通过runInInjectionContext包裹:

import { Injector, DestroyRef, inject, runInInjectionContext } from '@angular/core';
import { OverlayRef } from '@angular/cdk/overlay';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

export class MyTestClass {
  private destroyRef: DestroyRef;

  constructor(
    public overlay: OverlayRef,
    private injector: Injector
  ) {
    runInInjectionContext(this.injector, () => {
      this.destroyRef = inject(DestroyRef);
    });

    this.overlay
      .backdropClick()
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(() => {
        // 你的业务逻辑
      });
  }
}

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 16:03:33