錯誤百科

注入器已被銷毀

當你嘗試從一個已被銷毀的注入器中擷取服務時,就會發生這個錯誤。這通常發生在元件、指令或模組被銷毀之後,程式碼仍試圖存取其依賴。

常見情境

元件銷毀後在回呼中存取服務

當元件被銷毀時,它的注入器也會被銷毀。如果某個非同步回呼之後試圖存取服務,就會發生這個錯誤:

@Component(/* ... */)
export class UserProfile implements OnInit {
  private userClient = inject(UserClient);

  ngOnInit() {
    setTimeout(() => {
      // ERROR: If component was destroyed before timeout fires,
      // the injector is no longer available
      this.userClient.fetchData();
    }, 5000);
  }
}

取消訂閱後存取服務

當清理順序不正確時,observable 也會發生類似的問題:

@Component(/* ... */)
export class DataView implements OnDestroy {
  private dataStore = inject(DataStore);

  ngOnDestroy() {
    // Problematic: attempting to use the injector during destruction
    // after other cleanup may have occurred
    this.dataStore.cleanup();
  }
}

如何除錯

要修復這個錯誤:

  1. 檢查非同步操作——確保回呼、promise 與訂閱會在元件銷毀時被取消。使用 takeUntilDestroyed() 或 DestroyRef 來進行清理。

  2. 提早保存依賴——把服務的參考儲存在類別欄位中,而不是在回呼裡存取注入器。

  3. 防範已銷毀的狀態——對於可能比元件存活更久的操作,在存取服務之前,先檢查元件是否仍在作用中。

@Component(/* ... */)
export class UserProfile implements OnInit {
  private destroyRef = inject(DestroyRef);
  private userClient = inject(UserClient);

  ngOnInit() {
    // Use takeUntilDestroyed to automatically cancel when destroyed
    interval(5000)
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(() => {
        this.userClient.fetchData();
      });
  }
}

堆疊追蹤會指出已銷毀的注入器是在哪裡被存取的。請往回追蹤,找出那個比其元件存活更久的非同步操作。