diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index 8052b0ce28..223b8554fb 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -377,14 +377,14 @@ export function refreshView( try { resetPreOrderHookFlags(lView); - if (templateFn !== null) { - executeTemplate(lView, templateFn, RenderFlags.Update, context); - } - // Resetting the bindingIndex of the current LView as the next steps may trigger change // detection. lView[BINDING_INDEX] = tView.bindingStartIndex; + if (templateFn !== null) { + executeTemplate(lView, templateFn, RenderFlags.Update, context); + } + const checkNoChangesMode = getCheckNoChangesMode(); const hooksInitPhaseCompleted = (flags & LViewFlags.InitPhaseStateMask) === InitPhaseState.InitPhaseCompleted; diff --git a/packages/core/test/acceptance/change_detection_spec.ts b/packages/core/test/acceptance/change_detection_spec.ts index 59aa0c8f96..f808dabbac 100644 --- a/packages/core/test/acceptance/change_detection_spec.ts +++ b/packages/core/test/acceptance/change_detection_spec.ts @@ -8,7 +8,7 @@ import {CommonModule} from '@angular/common'; -import {ApplicationRef, ChangeDetectionStrategy, ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, Directive, DoCheck, EmbeddedViewRef, ErrorHandler, Input, NgModule, OnInit, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; +import {ApplicationRef, ChangeDetectionStrategy, ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, Directive, DoCheck, EmbeddedViewRef, ErrorHandler, Input, NgModule, OnInit, QueryList, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {expect} from '@angular/platform-browser/testing/src/matchers'; @@ -545,6 +545,44 @@ describe('change detection', () => { expect(fixture.nativeElement.textContent).toEqual('1'); }); + it('should support change detection triggered as a result of View queries processing', () => { + @Component({ + selector: 'app', + template: ` +
Visible text
+ ` + }) + class App { + @ViewChildren('ref') + ref !: QueryList; + + visible = false; + + constructor(public changeDetectorRef: ChangeDetectorRef) {} + + ngAfterViewInit() { + this.ref.changes.subscribe((refs: QueryList) => { + this.visible = false; + this.changeDetectorRef.detectChanges(); + }); + } + } + + TestBed.configureTestingModule({ + declarations: [App], + imports: [CommonModule], + }); + const fixture = TestBed.createComponent(App); + fixture.detectChanges(); + expect(fixture.nativeElement.textContent).toBe(''); + + // even though we set "visible" to `true`, we do not expect any content to be displayed, + // since the flag is overridden in `ngAfterViewInit` back to `false` + fixture.componentInstance.visible = true; + fixture.detectChanges(); + expect(fixture.nativeElement.textContent).toBe(''); + }); + describe('dynamic views', () => { @Component({selector: 'structural-comp', template: '{{ value }}'}) class StructuralComp {