feat(core): PlatformRef and ApplicationRef support registration of disposal functions.

These functions will be called whenever the platform or application are being disposed.
This commit is contained in:
Alex Rickabaugh 2015-10-26 10:50:25 -07:00
parent b2dc5c2c7e
commit 8dd3082ea3
3 changed files with 44 additions and 0 deletions

View File

@ -150,6 +150,11 @@ export function platformCommon(bindings?: Array<Type | Provider | any[]>, initia
* explicitly by calling {@link platform}(). * explicitly by calling {@link platform}().
*/ */
export abstract class PlatformRef { export abstract class PlatformRef {
/**
* Register a listener to be called when the platform is disposed.
*/
abstract registerDisposeListener(dispose: () => void): void;
/** /**
* Retrieve the platform {@link Injector}, which is the parent injector for * Retrieve the platform {@link Injector}, which is the parent injector for
* every Angular application on the page and provides singleton providers. * every Angular application on the page and provides singleton providers.
@ -210,9 +215,12 @@ export abstract class PlatformRef {
export class PlatformRef_ extends PlatformRef { export class PlatformRef_ extends PlatformRef {
/** @internal */ /** @internal */
_applications: ApplicationRef[] = []; _applications: ApplicationRef[] = [];
_disposeListeners: Function[] = [];
constructor(private _injector: Injector, private _dispose: () => void) { super(); } constructor(private _injector: Injector, private _dispose: () => void) { super(); }
registerDisposeListener(dispose: () => void): void { this._disposeListeners.push(dispose); }
get injector(): Injector { return this._injector; } get injector(): Injector { return this._injector; }
application(bindings: Array<Type | Provider | any[]>): ApplicationRef { application(bindings: Array<Type | Provider | any[]>): ApplicationRef {
@ -259,6 +267,7 @@ export class PlatformRef_ extends PlatformRef {
dispose(): void { dispose(): void {
this._applications.forEach((app) => app.dispose()); this._applications.forEach((app) => app.dispose());
this._disposeListeners.forEach((dispose) => dispose());
this._dispose(); this._dispose();
} }
@ -278,6 +287,11 @@ export abstract class ApplicationRef {
*/ */
abstract registerBootstrapListener(listener: (ref: ComponentRef) => void): void; abstract registerBootstrapListener(listener: (ref: ComponentRef) => void): void;
/**
* Register a listener to be called when the application is disposed.
*/
abstract registerDisposeListener(dispose: () => void): void;
/** /**
* Bootstrap a new component at the root level of the application. * Bootstrap a new component at the root level of the application.
* *
@ -326,6 +340,7 @@ export abstract class ApplicationRef {
export class ApplicationRef_ extends ApplicationRef { export class ApplicationRef_ extends ApplicationRef {
private _bootstrapListeners: Function[] = []; private _bootstrapListeners: Function[] = [];
private _disposeListeners: Function[] = [];
private _rootComponents: ComponentRef[] = []; private _rootComponents: ComponentRef[] = [];
private _rootComponentTypes: Type[] = []; private _rootComponentTypes: Type[] = [];
@ -337,6 +352,8 @@ export class ApplicationRef_ extends ApplicationRef {
this._bootstrapListeners.push(listener); this._bootstrapListeners.push(listener);
} }
registerDisposeListener(dispose: () => void): void { this._disposeListeners.push(dispose); }
bootstrap(componentType: Type, bootstrap(componentType: Type,
providers?: Array<Type | Provider | any[]>): Promise<ComponentRef> { providers?: Array<Type | Provider | any[]>): Promise<ComponentRef> {
var completer = PromiseWrapper.completer(); var completer = PromiseWrapper.completer();
@ -380,6 +397,7 @@ export class ApplicationRef_ extends ApplicationRef {
dispose(): void { dispose(): void {
// TODO(alxhub): Dispose of the NgZone. // TODO(alxhub): Dispose of the NgZone.
this._rootComponents.forEach((ref) => ref.dispose()); this._rootComponents.forEach((ref) => ref.dispose());
this._disposeListeners.forEach((dispose) => dispose());
this._platform._applicationDisposed(this); this._platform._applicationDisposed(this);
} }

View File

@ -0,0 +1,24 @@
import {ApplicationRef} from 'angular2/src/core/application_ref';
import {Type} from 'angular2/src/core/facade/lang';
import {ComponentRef} from 'angular2/src/core/linker/dynamic_component_loader';
import {Provider, Injector} from 'angular2/src/core/di';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {Promise} from 'angular2/src/core/facade/async';
export class MockApplicationRef extends ApplicationRef {
registerBootstrapListener(listener: (ref: ComponentRef) => void): void {}
registerDisposeListener(dispose: () => void): void {}
bootstrap(componentType: Type, bindings?: Array<Type | Provider | any[]>): Promise<ComponentRef> {
return null;
}
get injector(): Injector { return null; };
get zone(): NgZone { return null; };
dispose(): void {}
get componentTypes(): Type[] { return null; };
}

View File

@ -98,6 +98,7 @@ var NG_API = [
'ApplicationRef.bootstrap()', 'ApplicationRef.bootstrap()',
'ApplicationRef.dispose()', 'ApplicationRef.dispose()',
'ApplicationRef.registerBootstrapListener()', 'ApplicationRef.registerBootstrapListener()',
'ApplicationRef.registerDisposeListener()',
*/ */
'AsyncPipe', 'AsyncPipe',
'AsyncPipe.onDestroy()', 'AsyncPipe.onDestroy()',
@ -873,6 +874,7 @@ var NG_API = [
'PlatformRef.application()', 'PlatformRef.application()',
'PlatformRef.asyncApplication()', 'PlatformRef.asyncApplication()',
'PlatformRef.dispose()', 'PlatformRef.dispose()',
'PlatformRef.registerDisposeListener()',
*/ */
'PlatformRef.injector', 'PlatformRef.injector',
'Predicate:dart', 'Predicate:dart',