feat(bootstrap): add platform and app initializers

Often some init logic needs to run when a platform or an application is boostrapped.
For example, boostraping a platform requires initializing the dom adapter.
Now, it can be done as follows:

new Provider(PLATFORM_INITIALIZER, {useValue: initDomAdapter, multi: true}),

All platform initializers will be run after the platform injector has been created.

Similarly, all application initializers will be run after the app injector has been
created.

Closes #5355
This commit is contained in:
vsavkin
2015-11-18 09:18:37 -08:00
committed by Victor Savkin
parent 3fa287aae2
commit 3c43a8c549
9 changed files with 80 additions and 19 deletions

View File

@ -4,7 +4,9 @@ import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
import {
APP_COMPONENT_REF_PROMISE,
APP_COMPONENT,
APP_ID_RANDOM_PROVIDER
APP_ID_RANDOM_PROVIDER,
PLATFORM_INITIALIZER,
APP_INITIALIZER
} from './application_tokens';
import {
Promise,
@ -30,7 +32,6 @@ import {wtfLeave, wtfCreateScope, WtfScopeFn} from './profile/profile';
import {ChangeDetectorRef} from 'angular2/src/core/change_detection/change_detector_ref';
import {lockDevMode} from 'angular2/src/facade/lang';
/**
* Construct providers specific to an individual root component.
*/
@ -103,15 +104,32 @@ export function platform(providers?: Array<Type | Provider | any[]>): PlatformRe
}
}
/**
* Dispose the existing platform.
*/
export function disposePlatform(): void {
if (isPresent(_platform)) {
_platform.dispose();
_platform = null;
}
}
function _createPlatform(providers?: Array<Type | Provider | any[]>): PlatformRef {
_platformProviders = providers;
_platform = new PlatformRef_(Injector.resolveAndCreate(providers), () => {
let injector = Injector.resolveAndCreate(providers);
_platform = new PlatformRef_(injector, () => {
_platform = null;
_platformProviders = null;
});
_runPlatformInitializers(injector);
return _platform;
}
function _runPlatformInitializers(injector: Injector): void {
let inits: Function[] = injector.getOptional(PLATFORM_INITIALIZER);
if (isPresent(inits)) inits.forEach(init => init());
}
/**
* The Angular platform is the entry point for Angular on a web page. Each page
* has exactly one platform, and services (such as reflection) which are common
@ -236,11 +254,12 @@ export class PlatformRef_ extends PlatformRef {
});
app = new ApplicationRef_(this, zone, injector);
this._applications.push(app);
_runAppInitializers(injector);
return app;
}
dispose(): void {
this._applications.forEach((app) => app.dispose());
ListWrapper.clone(this._applications).forEach((app) => app.dispose());
this._disposeListeners.forEach((dispose) => dispose());
this._dispose();
}
@ -249,6 +268,11 @@ export class PlatformRef_ extends PlatformRef {
_applicationDisposed(app: ApplicationRef): void { ListWrapper.remove(this._applications, app); }
}
function _runAppInitializers(injector: Injector): void {
let inits: Function[] = injector.getOptional(APP_INITIALIZER);
if (isPresent(inits)) inits.forEach(init => init());
}
/**
* A reference to an Angular application running on a page.
*
@ -439,7 +463,7 @@ export class ApplicationRef_ extends ApplicationRef {
dispose(): void {
// TODO(alxhub): Dispose of the NgZone.
this._rootComponents.forEach((ref) => ref.dispose());
ListWrapper.clone(this._rootComponents).forEach((ref) => ref.dispose());
this._disposeListeners.forEach((dispose) => dispose());
this._platform._applicationDisposed(this);
}