SignalStore的onDestroy钩子未触发问题求助
The core issue here is how Angular handles lifecycle cleanup for services provided at the route level, and how you're registering your cleanup logic.
Key Mistake: Incorrect Cleanup Registration
Your current onDestroy(store) function isn't hooked into the destruction of the route's injector. Components and directives have built-in ngOnDestroy lifecycle hooks, but services don't—unless you use DestroyRef to register a cleanup callback tied to the injector that created the service.
When you moved the provider to the component level, the service's injector was tied to the component's lifecycle, so Angular triggered the cleanup when the component destroyed. But for route-level providers, you need to explicitly use DestroyRef to capture when the route's injector is destroyed.
Fix: Use DestroyRef in Your CoursesStore
Modify your CoursesStore to inject DestroyRef and register the state reset logic with it. This ensures the cleanup runs automatically when the route's injector is destroyed (when you navigate away from the route):
import { Injectable, DestroyRef } from '@angular/core'; import { patchState, SignalStore, withState } from '@ngrx/signals'; // Adjust import to match your Signal Store package const initialState = { /* Define your initial state here */ }; @Injectable() // No `providedIn: 'root'` to avoid singleton behavior export class CoursesStore extends SignalStore( withState(initialState) ) { constructor( private destroyRef: DestroyRef, private coursesService: CoursesService ) { super(); // Register cleanup logic to run when the route's injector is destroyed this.destroyRef.onDestroy(() => { console.log("destroy"); patchState(this, initialState); }); } // Add your store methods (API calls, state updates) here }
Why Route-Level Providers Work With DestroyRef
When you provide CoursesStore in the route's providers array, Angular creates an instance scoped to that route's injector. When you navigate away from the route (and it's no longer active), this injector is destroyed. The DestroyRef instance injected into the store is tied to this injector, so its onDestroy callback fires automatically.
Additional Checks
Confirm You're Navigating Outside the Route Tree: If you're navigating to a child route of the route that provides the store, the parent route's injector remains active—so the cleanup won't trigger. Only navigation outside the entire route tree containing the provider will destroy the injector.
Verify No Singleton Instances: Double-check that neither
CoursesStorenorCoursesServicehaveprovidedIn: 'root'in their@Injectabledecorator. Singleton services are never destroyed until the app closes.
Your Original Questions Answered
- Did you miss core hook mechanics?: Yes, component-style
onDestroyhooks are tied exclusively to component lifecycle. Services requireDestroyRefto track injector destruction. - Is using onDestroy at route level wrong?: No, but you need to use
DestroyRefinstead of component-style hooks. Route-level providers are valid, andDestroyReflets you tie cleanup logic directly to the route's lifecycle.
内容的提问来源于stack exchange,提问作者SomeStudent

