當你嘗試從一個已被銷毀的注入器中擷取服務時,就會發生這個錯誤。這通常發生在元件、指令或模組被銷毀之後,程式碼仍試圖存取其依賴。
常見情境
元件銷毀後在回呼中存取服務
當元件被銷毀時,它的注入器也會被銷毀。如果某個非同步回呼之後試圖存取服務,就會發生這個錯誤:
@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();
}
}
如何除錯
要修復這個錯誤:
檢查非同步操作——確保回呼、promise 與訂閱會在元件銷毀時被取消。使用
takeUntilDestroyed()或DestroyRef來進行清理。提早保存依賴——把服務的參考儲存在類別欄位中,而不是在回呼裡存取注入器。
防範已銷毀的狀態——對於可能比元件存活更久的操作,在存取服務之前,先檢查元件是否仍在作用中。
@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();
});
}
}
堆疊追蹤會指出已銷毀的注入器是在哪裡被存取的。請往回追蹤,找出那個比其元件存活更久的非同步操作。