diff --git a/modules/@angular/compiler/src/view_compiler/view_builder.ts b/modules/@angular/compiler/src/view_compiler/view_builder.ts index 104bf1f2c3..bf5d8409fe 100644 --- a/modules/@angular/compiler/src/view_compiler/view_builder.ts +++ b/modules/@angular/compiler/src/view_compiler/view_builder.ts @@ -557,7 +557,8 @@ function generateDetectChangesMethod(view: CompileView): o.Statement[] { view.updateContentQueriesMethod.isEmpty() && view.afterContentLifecycleCallbacksMethod.isEmpty() && view.detectChangesRenderPropertiesMethod.isEmpty() && - view.updateViewQueriesMethod.isEmpty() && view.afterViewLifecycleCallbacksMethod.isEmpty()) { + view.updateViewQueriesMethod.isEmpty() && view.afterViewLifecycleCallbacksMethod.isEmpty() && + view.viewContainers.length === 0 && view.viewChildren.length === 0) { return stmts; } stmts.push(...view.animationBindingsMethod.finish()); diff --git a/modules/@angular/core/test/linker/change_detection_integration_spec.ts b/modules/@angular/core/test/linker/change_detection_integration_spec.ts index 7294c2c9e3..a1d9f8962c 100644 --- a/modules/@angular/core/test/linker/change_detection_integration_spec.ts +++ b/modules/@angular/core/test/linker/change_detection_integration_spec.ts @@ -8,7 +8,7 @@ import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry'; import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/test_bindings'; -import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, DoCheck, Injectable, Input, OnChanges, OnDestroy, OnInit, Output, Pipe, PipeTransform, RenderComponentType, Renderer, RootRenderer, SimpleChange, SimpleChanges, TemplateRef, Type, ViewContainerRef, WrappedValue} from '@angular/core'; +import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, DebugElement, Directive, DoCheck, Injectable, Input, OnChanges, OnDestroy, OnInit, Output, Pipe, PipeTransform, RenderComponentType, Renderer, RootRenderer, SimpleChange, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, WrappedValue} from '@angular/core'; import {DebugDomRenderer} from '@angular/core/src/debug/debug_renderer'; import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing'; import {By} from '@angular/platform-browser/src/dom/debug/by'; @@ -1165,6 +1165,43 @@ export function main() { expect(directiveLog.filter(['set'])).toEqual(['0.set', '1.set', '2.set']); })); }); + + describe('nested view recursion', () => { + it('should recurse into nested components even if there are no bindings in the component view', + () => { + @Component({selector: 'nested', template: '{{name}}'}) + class Nested { + name = 'Tom'; + } + + TestBed.configureTestingModule({declarations: [Nested]}); + + const ctx = createCompFixture(''); + ctx.detectChanges(); + expect(renderLog.loggedValues).toEqual(['Tom']); + }); + + it('should recurse into nested view containers even if there are no bindings in the component view', + () => { + @Component({template: ''}) + class Comp { + name = 'Tom'; + @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef; + @ViewChild(TemplateRef) template: TemplateRef; + } + + TestBed.configureTestingModule({declarations: [Comp]}); + initHelpers(); + + const ctx = TestBed.createComponent(Comp); + ctx.detectChanges(); + expect(renderLog.loggedValues).toEqual([]); + + ctx.componentInstance.vc.createEmbeddedView(ctx.componentInstance.template); + ctx.detectChanges(); + expect(renderLog.loggedValues).toEqual(['Tom']); + }); + }); }); }