diff --git a/modules/signals/spec/signal-method.spec.ts b/modules/signals/spec/signal-method.spec.ts index ab554ff78a..aad3fef897 100644 --- a/modules/signals/spec/signal-method.spec.ts +++ b/modules/signals/spec/signal-method.spec.ts @@ -72,18 +72,15 @@ describe('signalMethod', () => { const adder = createAdder((value) => (a += value)); adder(summand1); adder(summand2); - - summand1.set(2); - summand2.set(3); TestBed.flushEffects(); - expect(a).toBe(6); + expect(a).toBe(4); adder.destroy(); summand1.set(2); summand2.set(3); TestBed.flushEffects(); - expect(a).toBe(6); + expect(a).toBe(4); }); it('does not cause issues if destroyed signalMethodFn contains destroyed effectRefs', () => { @@ -198,4 +195,23 @@ describe('signalMethod', () => { expect(a).toBe(5); }); }); + + it('stops specific tracking when calling destroy manually on an instance', () => { + let a = 1; + const summand1 = signal(1); + const summand2 = signal(2); + const adder = createAdder((value) => (a += value)); + adder(summand1); + const s2 = adder(summand2); + + TestBed.flushEffects(); + s2.destroy(); + expect(a).toBe(4); + + summand1.set(100); + summand2.set(3000); + + TestBed.flushEffects(); + expect(a).toBe(104); + }); }); diff --git a/modules/signals/src/signal-method.ts b/modules/signals/src/signal-method.ts index f9322e34c2..5a04c7e64d 100644 --- a/modules/signals/src/signal-method.ts +++ b/modules/signals/src/signal-method.ts @@ -1,5 +1,6 @@ import { assertInInjectionContext, + DestroyRef, effect, EffectRef, inject, @@ -35,15 +36,21 @@ export function signalMethod( config?.injector ?? getCallerInjector() ?? sourceInjector; const watcher = effect( - (onCleanup) => { + () => { const value = input(); untracked(() => processingFn(value)); - onCleanup(() => watchers.splice(watchers.indexOf(watcher), 1)); }, { injector: instanceInjector } ); watchers.push(watcher); + instanceInjector.get(DestroyRef).onDestroy(() => { + const ix = watchers.indexOf(watcher); + if (ix !== -1) { + watchers.splice(ix, 1); + } + }); + return watcher; } else { processingFn(input);