From 3edca4d37e121091356c0bda55f1916df6d6d140 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Wed, 14 Dec 2016 17:33:29 +0100 Subject: [PATCH] fix(core): properly destroy embedded Views attatched to ApplicationRef (#13459) Fixes #13062 --- modules/@angular/core/src/linker/view.ts | 3 ++- .../core/test/application_ref_spec.ts | 21 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/modules/@angular/core/src/linker/view.ts b/modules/@angular/core/src/linker/view.ts index 67b084b4d4..fc8ab9adb2 100644 --- a/modules/@angular/core/src/linker/view.ts +++ b/modules/@angular/core/src/linker/view.ts @@ -191,7 +191,8 @@ export abstract class AppView { } else { this._renderDetach(); } - if (this.declaredViewContainer && this.declaredViewContainer !== this.viewContainer) { + if (this.declaredViewContainer && this.declaredViewContainer !== this.viewContainer && + this.declaredViewContainer.projectedViews) { const projectedViews = this.declaredViewContainer.projectedViews; const index = projectedViews.indexOf(this); // perf: pop is faster than splice! diff --git a/modules/@angular/core/test/application_ref_spec.ts b/modules/@angular/core/test/application_ref_spec.ts index 61895f9eb0..5f5cbae71d 100644 --- a/modules/@angular/core/test/application_ref_spec.ts +++ b/modules/@angular/core/test/application_ref_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, CompilerFactory, Component, NgModule, PlatformRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; +import {APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, CompilerFactory, Component, NgModule, PlatformRef, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core'; import {ApplicationRef, ApplicationRef_} from '@angular/core/src/application_ref'; import {ErrorHandler} from '@angular/core/src/error_handler'; import {ComponentRef} from '@angular/core/src/linker/component_factory'; @@ -275,9 +275,15 @@ export function main() { vc: ViewContainerRef; } + @Component({template: ''}) + class EmbeddedViewComp { + @ViewChild(TemplateRef) + tplRef: TemplateRef; + } + beforeEach(() => { TestBed.configureTestingModule({ - declarations: [MyComp, ContainerComp], + declarations: [MyComp, ContainerComp, EmbeddedViewComp], providers: [{provide: ComponentFixtureNoNgZone, useValue: true}] }); }); @@ -321,6 +327,17 @@ export function main() { expect(appRef.viewCount).toBe(0); }); + it('should detach attached embedded views if they are destroyed', () => { + const comp = TestBed.createComponent(EmbeddedViewComp); + const appRef: ApplicationRef = TestBed.get(ApplicationRef); + const embeddedViewRef = comp.componentInstance.tplRef.createEmbeddedView({}); + + appRef.attachView(embeddedViewRef); + embeddedViewRef.destroy(); + + expect(appRef.viewCount).toBe(0); + }); + it('should not allow to attach a view to both, a view container and the ApplicationRef', () => { const comp = TestBed.createComponent(MyComp);