Skip to content

Commit

Permalink
fix(core): Document the new bootstrap APIs. Also rename rootBindings(…
Browse files Browse the repository at this point in the history
…) to platformBindings() to be more clear about what it is.

Closes #4218
  • Loading branch information
alxhub committed Sep 17, 2015
1 parent f490565 commit 06f8330
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 28 deletions.
36 changes: 30 additions & 6 deletions modules/angular2/src/core/application_common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,38 @@ export function applicationDomBindings(): Array<Type | Binding | any[]> {
];
}



/**
* Initialize the Angular context on the page.
* Initialize the Angular 'platform' on the page.
*
* See {@link PlatformRef} for details on the Angular platform.
*
* # Without specified bindings
*
* If no bindings are specified, `platform`'s behavior depends on whether an existing
* platform exists:
*
* If no platform exists, a new one will be created with the default {@link platformBindings}.
*
* If a platform already exists, it will be returned (regardless of what bindings it
* was created with). This is a convenience feature, allowing for multiple applications
* to be loaded into the same platform without awareness of each other.
*
* # With specified bindings
*
* It is also possible to specify bindings to be made in the new platform. These bindings
* will be shared between all applications on the page. For example, an abstraction for
* the browser cookie jar should be bound at the platform level, because there is only one
* cookie jar regardless of how many applications on the age will be accessing it.
*
* If bindings are specified directly, `platform` will create the Angular platform with
* them if a platform did not exist already. If it did exist, however, an error will be
* thrown.
*
* # DOM Applications
*
* If no bindings are provided, calling {@link platform}() is idempotent,
* and will use the default platform bindings (which can be obtained from
* {@link ApplicationRef/rootBindings}).
* This version of `platform` initializes Angular to run in the UI thread, with direct
* DOM access. Web-worker applications should call `platform` from
* `src/web_workers/worker/application_common` instead.
*/
export function platform(bindings?: Array<Type | Binding | any[]>): PlatformRef {
return platformCommon(bindings, () => {
Expand Down
97 changes: 75 additions & 22 deletions modules/angular2/src/core/application_ref.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {Type, isBlank, isPresent, assertionsEnabled} from 'angular2/src/core/facade/lang';
import {bind, Binding, Injector, OpaqueToken} from 'angular2/src/core/di';
Expand Down Expand Up @@ -47,9 +46,12 @@ import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mappe


/**
* Contains everything that is safe to share between applications.
* Constructs the set of bindings meant for use at the platform level.
*
* These are bindings that should be singletons shared among all Angular applications
* running on the page.
*/
export function rootBindings(): Array<Type | Binding | any[]> {
export function platformBindings(): Array<Type | Binding | any[]> {
return [bind(Reflector).toValue(reflector), TestabilityRegistry];
}

Expand Down Expand Up @@ -145,18 +147,19 @@ export function platformCommon(bindings?: Array<Type | Binding | any[]>, initial
}

if (isBlank(bindings)) {
bindings = rootBindings();
bindings = platformBindings();
}
_platform = new PlatformRef(Injector.resolveAndCreate(bindings), () => { _platform = null; });
return _platform;
}

/**
* Represent the Angular context on a page, and is a true singleton.
* 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
* to every Angular application running on the page are bound in its scope.
*
* The platform {@link Injector} injects dependencies which are also
* truly singletons in the context of a page (such as the browser's
* cookie jar).
* A page's platform is initialized implicitly when {@link bootstrap}() is called, or
* explicitly by calling {@link platform}().
*/
export class PlatformRef {
/**
Expand All @@ -170,25 +173,55 @@ export class PlatformRef {
constructor(private _injector: Injector, private _dispose: () => void) {}

/**
* Get the platform {@link Injector}.
* Retrieve the platform {@link Injector}, which is the parent injector for
* every Angular application on the page and provides singleton bindings.
*/
get injector(): Injector { return this._injector; }

/**
* Build a new Angular application with the given bindings. The `ApplicationRef`
* returned can be used to bootstrap one or more root components within the
* application.
* Instantiate a new Angular application on the page.
*
* # What is an application?
*
* Each Angular application has its own zone, change detection, compiler,
* renderer, and other framework components. An application hosts one or more
* root components, which can be initialized via `ApplicationRef.bootstrap()`.
*
* # Application Bindings
*
* Angular applications require numerous bindings to be properly instantiated.
* When using `application()` to create a new app on the page, these bindings
* must be provided. Fortunately, there are helper functions to configure
* typical bindings, as shown in the example below.
*
* # Example
* ```
* var myAppBindings = [MyAppService];
*
* platform()
* .application([applicationCommonBindings(), applicationDomBindings(), myAppBindings])
* .bootstrap(MyTopLevelComponent);
* ```
* # See Also
*
* See the {@link bootstrap} documentation for more details.
*/
application(bindings: Array<Type | Binding | any[]>): ApplicationRef {
var app = this._initApp(createNgZone(), bindings);
return app;
}

/**
* Build a new Angular application from asynchronously provided bindings.
* Instantiate a new Angular application on the page, using bindings which
* are only available asynchronously. One such use case is to initialize an
* application running in a web worker.
*
* Runs the `AsyncLoader` callback in the application `Zone` and constructs
* a new Application from the bindings provided by the `Promise` it returns.
* # Usage
*
* `bindingFn` is a function that will be called in the new application's zone.
* It should return a {@link Promise} to a list of bindings to be used for the
* new application. Once this promise resolves, the application will be
* constructed in the same manner as a normal `application()`.
*/
asyncApplication(bindingFn: (zone: NgZone) =>
Promise<Array<Type | Binding | any[]>>): Promise<ApplicationRef> {
Expand Down Expand Up @@ -242,11 +275,9 @@ export class PlatformRef {
}

/**
* Represents an Angular application.
* A reference to an Angular application running on a page.
*
* Use to retrieve the application {@link Injector} or to bootstrap new
* components at the root of the application. Can also be used to dispose
* of the entire application and all its loaded components.
* For more about Angular applications, see the documentation for {@link bootstrap}.
*/
export class ApplicationRef {
private _bootstrapListeners: Function[] = [];
Expand All @@ -258,15 +289,34 @@ export class ApplicationRef {
constructor(private _platform: PlatformRef, private _zone: NgZone, private _injector: Injector) {}

/**
* Register a listener to be called each time a new root component type is bootstrapped.
* Register a listener to be called each time `bootstrap()` is called to bootstrap
* a new root component.
*/
registerBootstrapListener(listener: (ref: ComponentRef) => void): void {
this._bootstrapListeners.push(listener);
}

/**
* Bootstrap a new component at the root level of the application, optionally with
* component specific bindings.
* Bootstrap a new component at the root level of the application.
*
* # Bootstrap process
*
* When bootstrapping a new root component into an application, Angular mounts the
* specified application component onto DOM elements identified by the [componentType]'s
* selector and kicks off automatic change detection to finish initializing the component.
*
* # Optional Bindings
*
* Bindings for the given component can optionally be overridden via the `bindings`
* parameter. These bindings will only apply for the root component being added and any
* child components under it.
*
* # Example
* ```
* var app = platform.application([applicationCommonBindings(), applicationDomBindings()];
* app.bootstrap(FirstRootComponent);
* app.bootstrap(SecondRootComponent, [bind(OverrideBinding).toClass(OverriddenBinding)]);
* ```
*/
bootstrap(componentType: Type, bindings?: Array<Type | Binding | any[]>): Promise<ComponentRef> {
var completer = PromiseWrapper.completer();
Expand Down Expand Up @@ -312,6 +362,9 @@ export class ApplicationRef {
*/
get zone(): NgZone { return this._zone; }

/**
* Dispose of this application and all of its components.
*/
dispose(): void {
// TODO(alxhub): Dispose of the NgZone.
this._rootComponents.forEach((ref) => ref.dispose());
Expand Down
36 changes: 36 additions & 0 deletions modules/angular2/src/web_workers/worker/application_common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,42 @@ import {WebWorkerEventDispatcher} from 'angular2/src/web_workers/worker/event_di
import {ComponentRef} from 'angular2/src/core/compiler/dynamic_component_loader';
import {NgZone} from 'angular2/src/core/zone/ng_zone';

/**
* Initialize the Angular 'platform' on the page in a manner suitable for applications
* running in a web worker. Applications running on a web worker do not have direct
* access to DOM APIs.
*
* See {@link PlatformRef} for details on the Angular platform.
*
* # Without specified bindings
*
* If no bindings are specified, `platform`'s behavior depends on whether an existing
* platform exists:
*
* If no platform exists, a new one will be created with the default {@link platformBindings}.
*
* If a platform already exists, it will be returned (regardless of what bindings it
* was created with). This is a convenience feature, allowing for multiple applications
* to be loaded into the same platform without awareness of each other.
*
* # With specified bindings
*
* It is also possible to specify bindings to be made in the new platform. These bindings
* will be shared between all applications on the page. For example, an abstraction for
* the browser cookie jar should be bound at the platform level, because there is only one
* cookie jar regardless of how many applications on the age will be accessing it.
*
* If bindings are specified directly, `platform` will create the Angular platform with
* them if a platform did not exist already. If it did exist, however, an error will be
* thrown.
*
* # For Web Worker Appplications
*
* This version of `platform` initializes Angular for use with applications
* that do not directly touch the DOM, such as applications which run in a
* web worker context. Applications that need direct access to the DOM should
* use `platform` from `core/application_common` instead.
*/
export function platform(bindings?: Array<Type | Binding | any[]>): PlatformRef {
return platformCommon(bindings);
}
Expand Down

0 comments on commit 06f8330

Please sign in to comment.