@@ -13,6 +13,7 @@ import {
13
13
consumerPollProducersForChange ,
14
14
getActiveConsumer ,
15
15
ReactiveNode ,
16
+ setActiveConsumer ,
16
17
} from '../../../primitives/signals' ;
17
18
18
19
import { RuntimeError , RuntimeErrorCode } from '../../errors' ;
@@ -207,7 +208,10 @@ export function refreshView<T>(
207
208
} else if ( getActiveConsumer ( ) === null ) {
208
209
// If the current view should not have a reactive consumer but we don't have an active consumer,
209
210
// we still need to create a temporary consumer to track any signal reads in this template.
210
- // This is a rare case that can happen with `viewContainerRef.createEmbeddedView(...).detectChanges()`.
211
+ // This is a rare case that can happen with
212
+ // - `viewContainerRef.createEmbeddedView(...).detectChanges()`.
213
+ // - `viewContainerRef.createEmbeddedView(...)` without any other dirty marking on the parent,
214
+ // flagging the parent component for traversal but not triggering a full `refreshView`.
211
215
// This temporary consumer marks the first parent that _should_ have a consumer for refresh.
212
216
// Once that refresh happens, the signals will be tracked in the parent consumer and we can destroy
213
217
// the temporary one.
@@ -490,16 +494,22 @@ function detectChangesInView(lView: LView, mode: ChangeDetectionMode) {
490
494
if ( shouldRefreshView ) {
491
495
refreshView ( tView , lView , tView . template , lView [ CONTEXT ] ) ;
492
496
} else if ( flags & LViewFlags . HasChildViewsToRefresh ) {
493
- if ( ! isInCheckNoChangesPass ) {
494
- runEffectsInView ( lView ) ;
495
- }
496
- detectChangesInEmbeddedViews ( lView , ChangeDetectionMode . Targeted ) ;
497
- const components = tView . components ;
498
- if ( components !== null ) {
499
- detectChangesInChildComponents ( lView , components , ChangeDetectionMode . Targeted ) ;
500
- }
501
- if ( ! isInCheckNoChangesPass ) {
502
- addAfterRenderSequencesForView ( lView ) ;
497
+ // Set active consumer to null to avoid inheriting an improper reactive context
498
+ const prevConsumer = setActiveConsumer ( null ) ;
499
+ try {
500
+ if ( ! isInCheckNoChangesPass ) {
501
+ runEffectsInView ( lView ) ;
502
+ }
503
+ detectChangesInEmbeddedViews ( lView , ChangeDetectionMode . Targeted ) ;
504
+ const components = tView . components ;
505
+ if ( components !== null ) {
506
+ detectChangesInChildComponents ( lView , components , ChangeDetectionMode . Targeted ) ;
507
+ }
508
+ if ( ! isInCheckNoChangesPass ) {
509
+ addAfterRenderSequencesForView ( lView ) ;
510
+ }
511
+ } finally {
512
+ setActiveConsumer ( prevConsumer ) ;
503
513
}
504
514
}
505
515
}
0 commit comments