能否在非组件/指令类中使用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
相关产品推荐
相关产品推荐

