fix(core): Run component disposal before destroyRootHostView() to avoid crash if change detection is triggered.

Closes #5226
This commit is contained in:
Alex Rickabaugh 2015-11-10 15:42:22 -08:00
parent 857bef9e4f
commit b22eddf1cb
2 changed files with 20 additions and 2 deletions

View File

@ -249,10 +249,10 @@ export class DynamicComponentLoader_ extends DynamicComponentLoader {
var component = this._viewManager.getComponent(newLocation); var component = this._viewManager.getComponent(newLocation);
var dispose = () => { var dispose = () => {
this._viewManager.destroyRootHostView(hostViewRef);
if (isPresent(onDispose)) { if (isPresent(onDispose)) {
onDispose(); onDispose();
} }
this._viewManager.destroyRootHostView(hostViewRef);
}; };
return new ComponentRef_(newLocation, component, type, injector, dispose); return new ComponentRef_(newLocation, component, type, injector, dispose);
}); });

View File

@ -13,7 +13,7 @@ import {
import {IS_DART, isPresent, stringify} from 'angular2/src/facade/lang'; import {IS_DART, isPresent, stringify} from 'angular2/src/facade/lang';
import {bootstrap} from 'angular2/platform/browser'; import {bootstrap} from 'angular2/platform/browser';
import {ApplicationRef} from 'angular2/src/core/application_ref'; import {ApplicationRef} from 'angular2/src/core/application_ref';
import {Component, Directive, View, platform} from 'angular2/core'; import {Component, Directive, View, OnDestroy, platform} from 'angular2/core';
import {BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS} from 'angular2/platform/browser'; import {BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
import {DOM} from 'angular2/src/core/dom/dom_adapter'; import {DOM} from 'angular2/src/core/dom/dom_adapter';
import {DOCUMENT} from 'angular2/render'; import {DOCUMENT} from 'angular2/render';
@ -67,6 +67,15 @@ class HelloRootMissingTemplate {
class HelloRootDirectiveIsNotCmp { class HelloRootDirectiveIsNotCmp {
} }
@Component({selector: 'hello-app'})
@View({template: ''})
class HelloOnDestroyTickCmp implements OnDestroy {
appRef: ApplicationRef;
constructor(@Inject(ApplicationRef) appRef) { this.appRef = appRef; }
onDestroy(): void { this.appRef.tick(); }
}
class _ArrayLogger { class _ArrayLogger {
res: any[] = []; res: any[] = [];
log(s: any): void { this.res.push(s); } log(s: any): void { this.res.push(s); }
@ -163,6 +172,15 @@ export function main() {
}); });
})); }));
it('should not crash if change detection is invoked when the root component is disposed',
inject([AsyncTestCompleter], (async) => {
bootstrap(HelloOnDestroyTickCmp, testProviders)
.then((ref) => {
expect(() => ref.dispose()).not.toThrow();
async.done();
});
}));
it('should unregister change detectors when components are disposed', it('should unregister change detectors when components are disposed',
inject([AsyncTestCompleter], (async) => { inject([AsyncTestCompleter], (async) => {
var app = platform(BROWSER_PROVIDERS).application([BROWSER_APP_PROVIDERS, testProviders]); var app = platform(BROWSER_PROVIDERS).application([BROWSER_APP_PROVIDERS, testProviders]);