feat(core): Add a long-form syntax for Angular bootstrapping.

This change adds a syntax for bootstrapping Angular on a page that allows more fine-grained control of the hierarchy created. platform() creates a platform injector (of which there can only be one). From the platform, .application() creates an Angular application including a Zone and all specified application bindings (e.g. for the DOM, HTTP, Compiler, Renderer, etc). At the application level, .bootstrap() will bootstrap the given component into that application.

Closes #3852
This commit is contained in:
Alex Rickabaugh
2015-09-02 15:19:26 -07:00
parent 193792c27f
commit 97d1844bfc
16 changed files with 503 additions and 408 deletions

View File

@ -1,11 +1,15 @@
import {Key, Injector, ResolvedBinding, Binding, bind, Injectable} from 'angular2/src/core/di';
import {Compiler} from './compiler';
import {Type, stringify, isPresent} from 'angular2/src/core/facade/lang';
import {isType, Type, stringify, isPresent} from 'angular2/src/core/facade/lang';
import {Promise} from 'angular2/src/core/facade/async';
import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
import {ElementRef} from './element_ref';
import {ViewRef, HostViewRef} from './view_ref';
function _asType(typeOrBinding: Type | Binding): Type {
return isType(typeOrBinding) ? typeOrBinding : (<Binding>typeOrBinding).token;
}
/**
* Angular's reference to a component instance.
*
@ -22,12 +26,20 @@ export class ComponentRef {
*/
instance: any;
componentType: Type;
injector: Injector;
/**
* @private
*/
constructor(location: ElementRef, instance: any, private _dispose: () => void) {
constructor(location: ElementRef, instance: any, componentType: Type, injector: Injector,
private _dispose: () => void) {
this.location = location;
this.instance = instance;
this.componentType = componentType;
this.injector = injector;
}
/**
@ -35,6 +47,10 @@ export class ComponentRef {
*/
get hostView(): HostViewRef { return this.location.parentView; }
get hostComponentType(): Type { return this.componentType; }
get hostComponent(): any { return this.instance; }
/**
* Dispose of the component instance.
*/
@ -104,8 +120,8 @@ export class DynamicComponentLoader {
* </my-app>
* ```
*/
loadAsRoot(typeOrBinding: Type | Binding, overrideSelector: string,
injector: Injector): Promise<ComponentRef> {
loadAsRoot(typeOrBinding: Type | Binding, overrideSelector: string, injector: Injector,
onDispose?: () => void): Promise<ComponentRef> {
return this._compiler.compileInHost(typeOrBinding)
.then(hostProtoViewRef => {
var hostViewRef =
@ -113,8 +129,14 @@ export class DynamicComponentLoader {
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);
var dispose = () => { this._viewManager.destroyRootHostView(hostViewRef); };
return new ComponentRef(newLocation, component, dispose);
var dispose = () => {
this._viewManager.destroyRootHostView(hostViewRef);
if (isPresent(onDispose)) {
onDispose();
}
};
return new ComponentRef(newLocation, component, _asType(typeOrBinding), injector,
dispose);
});
}
@ -229,7 +251,7 @@ export class DynamicComponentLoader {
viewContainer.remove(index);
}
};
return new ComponentRef(newLocation, component, dispose);
return new ComponentRef(newLocation, component, _asType(typeOrBinding), null, dispose);
});
}
}