Skip to content

Commit cdd519e

Browse files
tboschjimthedev
authored andcommitted
fix(dynamic_component_loader): check whether the dynamically loaded component has already been destroyed
Fixes angular#2748 Closes angular#2767
1 parent 620eaf4 commit cdd519e

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

modules/angular2/src/core/compiler/dynamic_component_loader.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ export class DynamicComponentLoader {
7373

7474
var dispose = () => {
7575
var index = viewContainer.indexOf(hostViewRef);
76-
viewContainer.remove(index);
76+
if (index !== -1) {
77+
viewContainer.remove(index);
78+
}
7779
};
7880
return new ComponentRef(newLocation, component, dispose);
7981
});

modules/angular2/test/core/compiler/dynamic_component_loader_spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ import {
1515
viewRootNodes,
1616
TestComponentBuilder,
1717
RootTestComponent,
18-
inspectElement
18+
inspectElement,
19+
By
1920
} from 'angular2/test_lib';
2021

2122
import {Injector} from 'angular2/di';
23+
import {NgIf} from 'angular2/directives';
2224
import {Component, View, onDestroy} from 'angular2/annotations';
2325
import * as viewAnn from 'angular2/src/core/annotations_impl/view';
2426
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
@@ -66,6 +68,37 @@ export function main() {
6668
});
6769
}));
6870

71+
it('should allow to dispose even if the location has been removed',
72+
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
73+
(loader, tcb: TestComponentBuilder, async) => {
74+
tcb.overrideView(MyComp, new viewAnn.View({
75+
template: '<child-cmp *ng-if="ctxBoolProp"></child-cmp>',
76+
directives: [NgIf, ChildComp]
77+
}))
78+
.overrideView(
79+
ChildComp,
80+
new viewAnn.View(
81+
{template: '<location #loc></location>', directives: [Location]}))
82+
.createAsync(MyComp)
83+
.then((tc) => {
84+
tc.componentInstance.ctxBoolProp = true;
85+
tc.detectChanges();
86+
var childCompEl = tc.query(By.css('child-cmp'));
87+
loader.loadIntoLocation(DynamicallyLoaded, childCompEl.elementRef, 'loc')
88+
.then(ref => {
89+
expect(tc.nativeElement).toHaveText("Location;DynamicallyLoaded;");
90+
91+
tc.componentInstance.ctxBoolProp = false;
92+
tc.detectChanges();
93+
expect(tc.nativeElement).toHaveText("");
94+
95+
ref.dispose();
96+
expect(tc.nativeElement).toHaveText("");
97+
async.done();
98+
});
99+
});
100+
}));
101+
69102
it('should update host properties',
70103
inject(
71104
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],

0 commit comments

Comments
 (0)