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 dispose = () => {
this._viewManager.destroyRootHostView(hostViewRef);
if (isPresent(onDispose)) {
onDispose();
}
this._viewManager.destroyRootHostView(hostViewRef);
};
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 {bootstrap} from 'angular2/platform/browser';
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 {DOM} from 'angular2/src/core/dom/dom_adapter';
import {DOCUMENT} from 'angular2/render';
@ -67,6 +67,15 @@ class HelloRootMissingTemplate {
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 {
res: any[] = [];
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',
inject([AsyncTestCompleter], (async) => {
var app = platform(BROWSER_PROVIDERS).application([BROWSER_APP_PROVIDERS, testProviders]);