feat(view): generalized loading of dynamic components
This commit is contained in:
parent
e9f70293ac
commit
f45281a10a
4
modules/angular2/core.js
vendored
4
modules/angular2/core.js
vendored
@ -9,8 +9,8 @@ export * from './src/core/compiler/compiler';
|
|||||||
|
|
||||||
// TODO(tbosch): remove this once render migration is complete
|
// TODO(tbosch): remove this once render migration is complete
|
||||||
export * from 'angular2/src/render/dom/compiler/template_loader';
|
export * from 'angular2/src/render/dom/compiler/template_loader';
|
||||||
export * from './src/core/compiler/private_component_loader';
|
export * from './src/core/compiler/dynamic_component_loader';
|
||||||
export * from './src/core/compiler/private_component_location';
|
export {ElementRef, DirectiveRef, ComponetRef} from './src/core/compiler/element_injector';
|
||||||
export * from './src/core/compiler/view';
|
export * from './src/core/compiler/view';
|
||||||
export * from './src/core/compiler/view_container';
|
export * from './src/core/compiler/view_container';
|
||||||
|
|
||||||
|
@ -590,7 +590,7 @@ export class Component extends Directive {
|
|||||||
* })
|
* })
|
||||||
* class DynamicComp {
|
* class DynamicComp {
|
||||||
* helloCmp:HelloCmp;
|
* helloCmp:HelloCmp;
|
||||||
* constructor(loader:PrivateComponentLoader, location:PrivateComponentLocation) {
|
* constructor(loader:DynamicComponentLoader, location:PrivateComponentLocation) {
|
||||||
* loader.load(HelloCmp, location).then((helloCmp) => {
|
* loader.load(HelloCmp, location).then((helloCmp) => {
|
||||||
* this.helloCmp = helloCmp;
|
* this.helloCmp = helloCmp;
|
||||||
* });
|
* });
|
||||||
|
56
modules/angular2/src/core/application.js
vendored
56
modules/angular2/src/core/application.js
vendored
@ -24,8 +24,7 @@ import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mappe
|
|||||||
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
import {UrlResolver} from 'angular2/src/services/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
|
||||||
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
||||||
import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
|
import {ViewFactory, VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_factory';
|
||||||
import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
|
import {ProtoViewFactory} from 'angular2/src/core/compiler/proto_view_factory';
|
||||||
@ -35,7 +34,7 @@ import * as rc from 'angular2/src/render/dom/compiler/compiler';
|
|||||||
import * as rvf from 'angular2/src/render/dom/view/view_factory';
|
import * as rvf from 'angular2/src/render/dom/view/view_factory';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
appViewToken,
|
appComponentRefToken,
|
||||||
appChangeDetectorToken,
|
appChangeDetectorToken,
|
||||||
appElementToken,
|
appElementToken,
|
||||||
appComponentAnnotatedTypeToken,
|
appComponentAnnotatedTypeToken,
|
||||||
@ -66,37 +65,20 @@ function _injectorBindings(appComponentType): List<Binding> {
|
|||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
}, [appComponentAnnotatedTypeToken, appDocumentToken]),
|
}, [appComponentAnnotatedTypeToken, appDocumentToken]),
|
||||||
bind(appViewToken).toAsyncFactory((changeDetection, compiler, injector, appElement,
|
bind(appComponentRefToken).toAsyncFactory((dynamicComponentLoader, injector, appElement,
|
||||||
appComponentAnnotatedType, testability, registry, viewFactory) => {
|
appComponentAnnotatedType, testability, registry) => {
|
||||||
|
|
||||||
// We need to do this here to ensure that we create Testability and
|
// We need to do this here to ensure that we create Testability and
|
||||||
// it's ready on the window for users.
|
// it's ready on the window for users.
|
||||||
registry.registerApplication(appElement, testability);
|
registry.registerApplication(appElement, testability);
|
||||||
var annotation = appComponentAnnotatedType.annotation;
|
return dynamicComponentLoader.loadIntoNewLocation(appElement, appComponentAnnotatedType.type, null, injector);
|
||||||
if(!isBlank(annotation) && !(annotation instanceof Component)) {
|
}, [DynamicComponentLoader, Injector, appElementToken, appComponentAnnotatedTypeToken,
|
||||||
var type = appComponentAnnotatedType.type;
|
Testability, TestabilityRegistry]),
|
||||||
throw new BaseException(`Only Components can be bootstrapped; ` +
|
|
||||||
`Directive of ${stringify(type)} is not a Component`);
|
|
||||||
}
|
|
||||||
return compiler.compileRoot(
|
|
||||||
appElement,
|
|
||||||
appComponentAnnotatedType.type
|
|
||||||
).then(
|
|
||||||
(appProtoView) => {
|
|
||||||
// The light Dom of the app element is not considered part of
|
|
||||||
// the angular application. Thus the context and lightDomInjector are
|
|
||||||
// empty.
|
|
||||||
var view = viewFactory.getView(appProtoView);
|
|
||||||
view.hydrate(injector, null, new Object(), null);
|
|
||||||
return view;
|
|
||||||
});
|
|
||||||
}, [ChangeDetection, Compiler, Injector, appElementToken, appComponentAnnotatedTypeToken,
|
|
||||||
Testability, TestabilityRegistry, ViewFactory]),
|
|
||||||
|
|
||||||
bind(appChangeDetectorToken).toFactory((rootView) => rootView.changeDetector,
|
bind(appChangeDetectorToken).toFactory((ref) => ref.hostView.changeDetector,
|
||||||
[appViewToken]),
|
[appComponentRefToken]),
|
||||||
bind(appComponentType).toFactory((rootView) => rootView.elementInjectors[0].getComponent(),
|
bind(appComponentType).toFactory((ref) => ref.instance,
|
||||||
[appViewToken]),
|
[appComponentRefToken]),
|
||||||
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(exceptionHandler, null, assertionsEnabled()),[ExceptionHandler]),
|
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(exceptionHandler, null, assertionsEnabled()),[ExceptionHandler]),
|
||||||
bind(EventManager).toFactory((zone) => {
|
bind(EventManager).toFactory((zone) => {
|
||||||
var plugins = [new HammerGesturesPlugin(), new DomEventsPlugin()];
|
var plugins = [new HammerGesturesPlugin(), new DomEventsPlugin()];
|
||||||
@ -136,8 +118,8 @@ function _injectorBindings(appComponentType): List<Binding> {
|
|||||||
UrlResolver,
|
UrlResolver,
|
||||||
StyleUrlResolver,
|
StyleUrlResolver,
|
||||||
StyleInliner,
|
StyleInliner,
|
||||||
PrivateComponentLoader,
|
DynamicComponentLoader,
|
||||||
Testability,
|
Testability
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,8 +242,8 @@ function _createVmZone(givenReporter:Function): VmTurnZone {
|
|||||||
* @publicModule angular2/angular2
|
* @publicModule angular2/angular2
|
||||||
*/
|
*/
|
||||||
export function bootstrap(appComponentType: Type,
|
export function bootstrap(appComponentType: Type,
|
||||||
componentServiceBindings: List<Binding>=null,
|
componentServiceBindings: List<Binding> = null,
|
||||||
errorReporter: Function=null): Promise<Injector> {
|
errorReporter: Function = null): Promise<Injector> {
|
||||||
BrowserDomAdapter.makeCurrent();
|
BrowserDomAdapter.makeCurrent();
|
||||||
var bootstrapProcess = PromiseWrapper.completer();
|
var bootstrapProcess = PromiseWrapper.completer();
|
||||||
|
|
||||||
@ -272,11 +254,11 @@ export function bootstrap(appComponentType: Type,
|
|||||||
|
|
||||||
var appInjector = _createAppInjector(appComponentType, componentServiceBindings, zone);
|
var appInjector = _createAppInjector(appComponentType, componentServiceBindings, zone);
|
||||||
|
|
||||||
PromiseWrapper.then(appInjector.asyncGet(appViewToken),
|
PromiseWrapper.then(appInjector.asyncGet(appChangeDetectorToken),
|
||||||
(rootView) => {
|
(appChangeDetector) => {
|
||||||
// retrieve life cycle: may have already been created if injected in root component
|
// retrieve life cycle: may have already been created if injected in root component
|
||||||
var lc=appInjector.get(LifeCycle);
|
var lc = appInjector.get(LifeCycle);
|
||||||
lc.registerWith(zone, rootView.changeDetector);
|
lc.registerWith(zone, appChangeDetector);
|
||||||
lc.tick(); //the first tick that will bootstrap the app
|
lc.tick(); //the first tick that will bootstrap the app
|
||||||
|
|
||||||
bootstrapProcess.resolve(appInjector);
|
bootstrapProcess.resolve(appInjector);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {OpaqueToken} from 'angular2/di';
|
import {OpaqueToken} from 'angular2/di';
|
||||||
|
|
||||||
export var appViewToken = new OpaqueToken('AppView');
|
export var appComponentRefToken = new OpaqueToken('ComponentRef');
|
||||||
export var appChangeDetectorToken = new OpaqueToken('AppChangeDetector');
|
export var appChangeDetectorToken = new OpaqueToken('AppChangeDetector');
|
||||||
export var appElementToken = new OpaqueToken('AppElement');
|
export var appElementToken = new OpaqueToken('AppElement');
|
||||||
export var appComponentAnnotatedTypeToken = new OpaqueToken('AppComponentAnnotatedType');
|
export var appComponentAnnotatedTypeToken = new OpaqueToken('AppComponentAnnotatedType');
|
||||||
|
99
modules/angular2/src/core/compiler/dynamic_component_loader.js
vendored
Normal file
99
modules/angular2/src/core/compiler/dynamic_component_loader.js
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import {Key, Injector, Injectable} from 'angular2/di'
|
||||||
|
import {Compiler} from './compiler';
|
||||||
|
import {DirectiveMetadataReader} from './directive_metadata_reader';
|
||||||
|
import {Type, BaseException, stringify, isPresent} from 'angular2/src/facade/lang';
|
||||||
|
import {Promise} from 'angular2/src/facade/async';
|
||||||
|
import {Component} from 'angular2/src/core/annotations/annotations';
|
||||||
|
import {ViewFactory} from 'angular2/src/core/compiler/view_factory';
|
||||||
|
import {Renderer} from 'angular2/src/render/api';
|
||||||
|
import {ElementRef, DirectiveRef, ComponentRef} from './element_injector';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for dynamically loading a Component into an arbitrary position in the internal Angular
|
||||||
|
* application tree.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class DynamicComponentLoader {
|
||||||
|
_compiler:Compiler;
|
||||||
|
_viewFactory:ViewFactory;
|
||||||
|
_renderer:Renderer;
|
||||||
|
_directiveMetadataReader:DirectiveMetadataReader;
|
||||||
|
|
||||||
|
constructor(compiler:Compiler, directiveMetadataReader:DirectiveMetadataReader,
|
||||||
|
renderer:Renderer, viewFactory:ViewFactory) {
|
||||||
|
this._compiler = compiler;
|
||||||
|
this._directiveMetadataReader = directiveMetadataReader;
|
||||||
|
this._renderer = renderer;
|
||||||
|
this._viewFactory = viewFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a component into the location given by the provided ElementRef. The loaded component
|
||||||
|
* receives injection as if it in the place of the provided ElementRef.
|
||||||
|
*/
|
||||||
|
loadIntoExistingLocation(type:Type, location:ElementRef, injector:Injector = null):Promise<ComponentRef> {
|
||||||
|
this._assertTypeIsComponent(type);
|
||||||
|
|
||||||
|
var annotation = this._directiveMetadataReader.read(type).annotation;
|
||||||
|
|
||||||
|
var inj = this._componentAppInjector(location, injector, annotation.services);
|
||||||
|
|
||||||
|
var hostEi = location.elementInjector;
|
||||||
|
var hostView = location.hostView;
|
||||||
|
|
||||||
|
return this._compiler.compile(type).then(componentProtoView => {
|
||||||
|
var context = hostEi.dynamicallyCreateComponent(type, annotation, inj);
|
||||||
|
var componentView = this._instantiateAndHydrateView(componentProtoView, injector, hostEi, context);
|
||||||
|
|
||||||
|
//TODO(vsavkin): do not use component child views as we need to clear the dynamically created views
|
||||||
|
//same problem exists on the render side
|
||||||
|
hostView.addComponentChildView(componentView);
|
||||||
|
|
||||||
|
this._renderer.setDynamicComponentView(hostView.render, location.boundElementIndex, componentView.render);
|
||||||
|
|
||||||
|
// TODO(vsavkin): return a component ref that dehydrates the component view and removes it
|
||||||
|
// from the component child views
|
||||||
|
return new ComponentRef(Key.get(type), hostEi, componentView);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a component as a child of the View given by the provided ElementRef. The loaded
|
||||||
|
* component receives injection normally as a hosted view.
|
||||||
|
*
|
||||||
|
* TODO(vsavkin, jelbourn): remove protoViewFactory after render layer exists.
|
||||||
|
*/
|
||||||
|
loadIntoNewLocation(elementOrSelector:any, type:Type, location:ElementRef,
|
||||||
|
injector:Injector = null):Promise<ComponentRef> {
|
||||||
|
this._assertTypeIsComponent(type);
|
||||||
|
|
||||||
|
var inj = this._componentAppInjector(location, injector, null);
|
||||||
|
|
||||||
|
//TODO(tbosch) this should always be a selector
|
||||||
|
return this._compiler.compileRoot(elementOrSelector, type).then(pv => {
|
||||||
|
var hostView = this._instantiateAndHydrateView(pv, inj, null, new Object());
|
||||||
|
|
||||||
|
// TODO(vsavkin): return a component ref that dehydrates the host view
|
||||||
|
return new ComponentRef(Key.get(type), hostView.elementInjectors[0], hostView.componentChildViews[0]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_componentAppInjector(location, injector, services) {
|
||||||
|
var inj = isPresent(injector) ? injector : location.elementInjector.getLightDomAppInjector();
|
||||||
|
return isPresent(services) ? inj.createChild(services) : inj;
|
||||||
|
}
|
||||||
|
|
||||||
|
_instantiateAndHydrateView(protoView, injector, hostElementInjector, context) {
|
||||||
|
var componentView = this._viewFactory.getView(protoView);
|
||||||
|
componentView.hydrate(injector, hostElementInjector, context, null);
|
||||||
|
return componentView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Asserts that the type being dynamically instantiated is a Component. */
|
||||||
|
_assertTypeIsComponent(type:Type) {
|
||||||
|
var annotation = this._directiveMetadataReader.read(type).annotation;
|
||||||
|
if (!(annotation instanceof Component)) {
|
||||||
|
throw new BaseException(`Could not load '${stringify(type)}' because it is not a component.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,6 @@ import {ViewContainer} from 'angular2/src/core/compiler/view_container';
|
|||||||
import {NgElement} from 'angular2/src/core/compiler/ng_element';
|
import {NgElement} from 'angular2/src/core/compiler/ng_element';
|
||||||
import {Directive, onChange, onDestroy, onAllChangesDone} from 'angular2/src/core/annotations/annotations';
|
import {Directive, onChange, onDestroy, onAllChangesDone} from 'angular2/src/core/annotations/annotations';
|
||||||
import {BindingPropagationConfig} from 'angular2/change_detection';
|
import {BindingPropagationConfig} from 'angular2/change_detection';
|
||||||
import * as pclModule from 'angular2/src/core/compiler/private_component_location';
|
|
||||||
import {QueryList} from './query_list';
|
import {QueryList} from './query_list';
|
||||||
|
|
||||||
var _MAX_DIRECTIVE_CONSTRUCTION_COUNTER = 10;
|
var _MAX_DIRECTIVE_CONSTRUCTION_COUNTER = 10;
|
||||||
@ -20,12 +19,50 @@ var _undefined = new Object();
|
|||||||
|
|
||||||
var _staticKeys;
|
var _staticKeys;
|
||||||
|
|
||||||
|
export class ElementRef {
|
||||||
|
elementInjector:ElementInjector;
|
||||||
|
|
||||||
|
constructor(elementInjector:ElementInjector){
|
||||||
|
this.elementInjector = elementInjector;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hostView() {
|
||||||
|
return this.elementInjector.getHostView();
|
||||||
|
}
|
||||||
|
|
||||||
|
get boundElementIndex() {
|
||||||
|
return this.elementInjector.getBoundElementIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DirectiveRef extends ElementRef {
|
||||||
|
_key:Key;
|
||||||
|
|
||||||
|
constructor(key:Key, elementInjector:ElementInjector){
|
||||||
|
super(elementInjector);
|
||||||
|
this._key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
get instance() {
|
||||||
|
return this.elementInjector.get(this._key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ComponentRef extends DirectiveRef {
|
||||||
|
componentView:viewModule.View;
|
||||||
|
|
||||||
|
constructor(key:Key, elementInjector:ElementInjector, componentView:viewModule.View){
|
||||||
|
super(key, elementInjector);
|
||||||
|
this.componentView = componentView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class StaticKeys {
|
class StaticKeys {
|
||||||
viewId:number;
|
viewId:number;
|
||||||
ngElementId:number;
|
ngElementId:number;
|
||||||
viewContainerId:number;
|
viewContainerId:number;
|
||||||
bindingPropagationConfigId:number;
|
bindingPropagationConfigId:number;
|
||||||
privateComponentLocationId:number;
|
directiveRefId:number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
|
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
|
||||||
@ -33,7 +70,7 @@ class StaticKeys {
|
|||||||
this.ngElementId = Key.get(NgElement).id;
|
this.ngElementId = Key.get(NgElement).id;
|
||||||
this.viewContainerId = Key.get(ViewContainer).id;
|
this.viewContainerId = Key.get(ViewContainer).id;
|
||||||
this.bindingPropagationConfigId = Key.get(BindingPropagationConfig).id;
|
this.bindingPropagationConfigId = Key.get(BindingPropagationConfig).id;
|
||||||
this.privateComponentLocationId = Key.get(pclModule.PrivateComponentLocation).id;
|
this.directiveRefId = Key.get(DirectiveRef).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static instance() {
|
static instance() {
|
||||||
@ -200,32 +237,40 @@ export class DirectiveDependency extends Dependency {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static createFrom(d:Dependency):Dependency {
|
static createFrom(d:Dependency):Dependency {
|
||||||
var depth = 0;
|
return new DirectiveDependency(d.key, d.asPromise, d.lazy, d.optional,
|
||||||
var eventName = null;
|
d.properties, DirectiveDependency._depth(d.properties),
|
||||||
var propName = null;
|
DirectiveDependency._eventEmitterName(d.properties),
|
||||||
var attributeName = null;
|
DirectiveDependency._propSetterName(d.properties),
|
||||||
var properties = d.properties;
|
DirectiveDependency._attributeName(d.properties),
|
||||||
var queryDirective = null;
|
DirectiveDependency._query(d.properties)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < properties.length; i++) {
|
static _depth(properties):int {
|
||||||
var property = properties[i];
|
if (properties.length == 0) return 0;
|
||||||
if (property instanceof Parent) {
|
if (ListWrapper.any(properties, p => p instanceof Parent)) return 1;
|
||||||
depth = 1;
|
if (ListWrapper.any(properties, p => p instanceof Ancestor)) return MAX_DEPTH;
|
||||||
} else if (property instanceof Ancestor) {
|
return 0;
|
||||||
depth = MAX_DEPTH;
|
}
|
||||||
} else if (property instanceof EventEmitter) {
|
|
||||||
eventName = property.eventName;
|
|
||||||
} else if (property instanceof PropertySetter) {
|
|
||||||
propName = property.propName;
|
|
||||||
} else if (property instanceof Attribute) {
|
|
||||||
attributeName = property.attributeName;
|
|
||||||
} else if (property instanceof Query) {
|
|
||||||
queryDirective = property.directive;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DirectiveDependency(d.key, d.asPromise, d.lazy, d.optional, d.properties, depth,
|
static _eventEmitterName(properties):string {
|
||||||
eventName, propName, attributeName, queryDirective);
|
var p = ListWrapper.find(properties, (p) => p instanceof EventEmitter);
|
||||||
|
return isPresent(p) ? p.eventName : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _propSetterName(properties):string {
|
||||||
|
var p = ListWrapper.find(properties, (p) => p instanceof PropertySetter);
|
||||||
|
return isPresent(p) ? p.propName : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _attributeName(properties):string {
|
||||||
|
var p = ListWrapper.find(properties, (p) => p instanceof Attribute);
|
||||||
|
return isPresent(p) ? p.attributeName : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _query(properties) {
|
||||||
|
var p = ListWrapper.find(properties, (p) => p instanceof Query);
|
||||||
|
return isPresent(p) ? p.directive : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,6 +470,8 @@ export class ElementInjector extends TreeNode {
|
|||||||
_lightDomAppInjector:Injector;
|
_lightDomAppInjector:Injector;
|
||||||
_shadowDomAppInjector:Injector;
|
_shadowDomAppInjector:Injector;
|
||||||
_host:ElementInjector;
|
_host:ElementInjector;
|
||||||
|
|
||||||
|
// If this element injector has a component, the component instance will be stored in _obj0
|
||||||
_obj0:any;
|
_obj0:any;
|
||||||
_obj1:any;
|
_obj1:any;
|
||||||
_obj2:any;
|
_obj2:any;
|
||||||
@ -437,8 +484,9 @@ export class ElementInjector extends TreeNode {
|
|||||||
_obj9:any;
|
_obj9:any;
|
||||||
_preBuiltObjects;
|
_preBuiltObjects;
|
||||||
_constructionCounter;
|
_constructionCounter;
|
||||||
_privateComponent;
|
|
||||||
_privateComponentBinding:DirectiveBinding;
|
_dynamicallyCreatedComponent:any;
|
||||||
|
_dynamicallyCreatedComponentBinding:DirectiveBinding;
|
||||||
|
|
||||||
// Queries are added during construction or linking with a new parent.
|
// Queries are added during construction or linking with a new parent.
|
||||||
// They are never removed.
|
// They are never removed.
|
||||||
@ -450,7 +498,6 @@ export class ElementInjector extends TreeNode {
|
|||||||
this._proto = proto;
|
this._proto = proto;
|
||||||
|
|
||||||
//we cannot call clearDirectives because fields won't be detected
|
//we cannot call clearDirectives because fields won't be detected
|
||||||
this._host = null;
|
|
||||||
this._preBuiltObjects = null;
|
this._preBuiltObjects = null;
|
||||||
this._lightDomAppInjector = null;
|
this._lightDomAppInjector = null;
|
||||||
this._shadowDomAppInjector = null;
|
this._shadowDomAppInjector = null;
|
||||||
@ -488,8 +535,8 @@ export class ElementInjector extends TreeNode {
|
|||||||
if (isPresent(p._binding7) && p._binding7.callOnDestroy) {this._obj7.onDestroy();}
|
if (isPresent(p._binding7) && p._binding7.callOnDestroy) {this._obj7.onDestroy();}
|
||||||
if (isPresent(p._binding8) && p._binding8.callOnDestroy) {this._obj8.onDestroy();}
|
if (isPresent(p._binding8) && p._binding8.callOnDestroy) {this._obj8.onDestroy();}
|
||||||
if (isPresent(p._binding9) && p._binding9.callOnDestroy) {this._obj9.onDestroy();}
|
if (isPresent(p._binding9) && p._binding9.callOnDestroy) {this._obj9.onDestroy();}
|
||||||
if (isPresent(this._privateComponentBinding) && this._privateComponentBinding.callOnDestroy) {
|
if (isPresent(this._dynamicallyCreatedComponentBinding) && this._dynamicallyCreatedComponentBinding.callOnDestroy) {
|
||||||
this._privateComponent.onDestroy();
|
this._dynamicallyCreatedComponent.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._obj0 = null;
|
this._obj0 = null;
|
||||||
@ -502,7 +549,8 @@ export class ElementInjector extends TreeNode {
|
|||||||
this._obj7 = null;
|
this._obj7 = null;
|
||||||
this._obj8 = null;
|
this._obj8 = null;
|
||||||
this._obj9 = null;
|
this._obj9 = null;
|
||||||
this._privateComponent = null;
|
this._dynamicallyCreatedComponent = null;
|
||||||
|
this._dynamicallyCreatedComponentBinding = null;
|
||||||
|
|
||||||
this._constructionCounter = 0;
|
this._constructionCounter = 0;
|
||||||
}
|
}
|
||||||
@ -526,15 +574,13 @@ export class ElementInjector extends TreeNode {
|
|||||||
if (isPresent(p._keyId7)) this._getDirectiveByKeyId(p._keyId7);
|
if (isPresent(p._keyId7)) this._getDirectiveByKeyId(p._keyId7);
|
||||||
if (isPresent(p._keyId8)) this._getDirectiveByKeyId(p._keyId8);
|
if (isPresent(p._keyId8)) this._getDirectiveByKeyId(p._keyId8);
|
||||||
if (isPresent(p._keyId9)) this._getDirectiveByKeyId(p._keyId9);
|
if (isPresent(p._keyId9)) this._getDirectiveByKeyId(p._keyId9);
|
||||||
if (isPresent(this._privateComponentBinding)) {
|
|
||||||
this._privateComponent = this._new(this._privateComponentBinding);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createPrivateComponent(componentType:Type, annotation:Directive) {
|
dynamicallyCreateComponent(componentType:Type, annotation:Directive, injector:Injector) {
|
||||||
this._privateComponentBinding = DirectiveBinding.createFromType(componentType, annotation);
|
this._shadowDomAppInjector = injector;
|
||||||
this._privateComponent = this._new(this._privateComponentBinding);
|
this._dynamicallyCreatedComponentBinding = DirectiveBinding.createFromType(componentType, annotation);
|
||||||
return this._privateComponent;
|
this._dynamicallyCreatedComponent = this._new(this._dynamicallyCreatedComponentBinding);
|
||||||
|
return this._dynamicallyCreatedComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkShadowDomAppInjector(shadowDomAppInjector:Injector) {
|
_checkShadowDomAppInjector(shadowDomAppInjector:Injector) {
|
||||||
@ -546,9 +592,18 @@ export class ElementInjector extends TreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get(token) {
|
get(token) {
|
||||||
|
if (this._isDynamicallyLoadedComponent(token)) {
|
||||||
|
return this._dynamicallyCreatedComponent;
|
||||||
|
}
|
||||||
|
|
||||||
return this._getByKey(Key.get(token), 0, false, null);
|
return this._getByKey(Key.get(token), 0, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_isDynamicallyLoadedComponent(token) {
|
||||||
|
return isPresent(this._dynamicallyCreatedComponentBinding) &&
|
||||||
|
Key.get(token) === this._dynamicallyCreatedComponentBinding.key;
|
||||||
|
}
|
||||||
|
|
||||||
hasDirective(type:Type):boolean {
|
hasDirective(type:Type):boolean {
|
||||||
return this._getDirectiveByKeyId(Key.get(type).id) !== _undefined;
|
return this._getDirectiveByKeyId(Key.get(type).id) !== _undefined;
|
||||||
}
|
}
|
||||||
@ -563,20 +618,25 @@ export class ElementInjector extends TreeNode {
|
|||||||
return this._preBuiltObjects.element;
|
return this._preBuiltObjects.element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the View associated with this ElementInjector */
|
||||||
|
getHostView() {
|
||||||
|
return this._preBuiltObjects.view;
|
||||||
|
}
|
||||||
|
|
||||||
getComponent() {
|
getComponent() {
|
||||||
if (this._proto._binding0IsComponent) {
|
if (this._proto._binding0IsComponent) {
|
||||||
return this._obj0;
|
return this._obj0;
|
||||||
} else {
|
} else {
|
||||||
throw new BaseException('There is not component stored in this ElementInjector');
|
throw new BaseException('There is no component stored in this ElementInjector');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getPrivateComponent() {
|
getDynamicallyLoadedComponent() {
|
||||||
return this._privateComponent;
|
return this._dynamicallyCreatedComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
getShadowDomAppInjector() {
|
getLightDomAppInjector() {
|
||||||
return this._shadowDomAppInjector;
|
return this._lightDomAppInjector;
|
||||||
}
|
}
|
||||||
|
|
||||||
directParent(): ElementInjector {
|
directParent(): ElementInjector {
|
||||||
@ -587,8 +647,9 @@ export class ElementInjector extends TreeNode {
|
|||||||
return this._proto._binding0IsComponent && key.id === this._proto._keyId0;
|
return this._proto._binding0IsComponent && key.id === this._proto._keyId0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isPrivateComponentKey(key:Key) {
|
_isDynamicallyLoadedComponentKey(key:Key) {
|
||||||
return isPresent(this._privateComponentBinding) && key.id === this._privateComponentBinding.key.id;
|
return isPresent(this._dynamicallyCreatedComponentBinding) && key.id ===
|
||||||
|
this._dynamicallyCreatedComponentBinding.key.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
_new(binding:Binding) {
|
_new(binding:Binding) {
|
||||||
@ -647,6 +708,10 @@ export class ElementInjector extends TreeNode {
|
|||||||
if (isPresent(dep.propSetterName)) return this._buildPropSetter(dep);
|
if (isPresent(dep.propSetterName)) return this._buildPropSetter(dep);
|
||||||
if (isPresent(dep.attributeName)) return this._buildAttribute(dep);
|
if (isPresent(dep.attributeName)) return this._buildAttribute(dep);
|
||||||
if (isPresent(dep.queryDirective)) return this._findQuery(dep.queryDirective).list;
|
if (isPresent(dep.queryDirective)) return this._findQuery(dep.queryDirective).list;
|
||||||
|
if (dep.key.id === StaticKeys.instance().directiveRefId) {
|
||||||
|
// TODO: we need store component view here and pass it to directive ref
|
||||||
|
return new DirectiveRef(requestor, this);
|
||||||
|
}
|
||||||
return this._getByKey(dep.key, dep.depth, dep.optional, requestor);
|
return this._getByKey(dep.key, dep.depth, dep.optional, requestor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,10 +884,11 @@ export class ElementInjector extends TreeNode {
|
|||||||
ei = ei._parent;
|
ei = ei._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isPresent(this._host) && this._host._isComponentKey(key)) {
|
if (isPresent(this._host) && this._host._isComponentKey(key)) {
|
||||||
return this._host.getComponent();
|
return this._host.getComponent();
|
||||||
} else if (isPresent(this._host) && this._host._isPrivateComponentKey(key)) {
|
} else if (isPresent(this._host) && this._host._isDynamicallyLoadedComponentKey(key)) {
|
||||||
return this._host.getPrivateComponent();
|
return this._host.getDynamicallyLoadedComponent();
|
||||||
} else if (optional) {
|
} else if (optional) {
|
||||||
return this._appInjector(requestor).getOptional(key);
|
return this._appInjector(requestor).getOptional(key);
|
||||||
} else {
|
} else {
|
||||||
@ -831,7 +897,7 @@ export class ElementInjector extends TreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_appInjector(requestor:Key) {
|
_appInjector(requestor:Key) {
|
||||||
if (isPresent(requestor) && this._isComponentKey(requestor)) {
|
if (isPresent(requestor) && (this._isComponentKey(requestor) || this._isDynamicallyLoadedComponentKey(requestor))) {
|
||||||
return this._shadowDomAppInjector;
|
return this._shadowDomAppInjector;
|
||||||
} else {
|
} else {
|
||||||
return this._lightDomAppInjector;
|
return this._lightDomAppInjector;
|
||||||
@ -850,10 +916,6 @@ export class ElementInjector extends TreeNode {
|
|||||||
if (keyId === staticKeys.viewContainerId) return this._preBuiltObjects.viewContainer;
|
if (keyId === staticKeys.viewContainerId) return this._preBuiltObjects.viewContainer;
|
||||||
if (keyId === staticKeys.bindingPropagationConfigId) return this._preBuiltObjects.bindingPropagationConfig;
|
if (keyId === staticKeys.bindingPropagationConfigId) return this._preBuiltObjects.bindingPropagationConfig;
|
||||||
|
|
||||||
if (keyId === staticKeys.privateComponentLocationId) {
|
|
||||||
return new pclModule.PrivateComponentLocation(this, this._preBuiltObjects.view);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO add other objects as needed
|
//TODO add other objects as needed
|
||||||
return _undefined;
|
return _undefined;
|
||||||
}
|
}
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
import {Compiler} from './compiler';
|
|
||||||
import {ViewFactory} from './view_factory';
|
|
||||||
import {Injectable} from 'angular2/di';
|
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
|
||||||
import {Component} from 'angular2/src/core/annotations/annotations';
|
|
||||||
import {PrivateComponentLocation} from './private_component_location';
|
|
||||||
import {Type, stringify, BaseException} from 'angular2/src/facade/lang';
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class PrivateComponentLoader {
|
|
||||||
compiler:Compiler;
|
|
||||||
directiveMetadataReader:DirectiveMetadataReader;
|
|
||||||
viewFactory:ViewFactory;
|
|
||||||
|
|
||||||
constructor(compiler:Compiler, directiveMetadataReader:DirectiveMetadataReader, viewFactory:ViewFactory) {
|
|
||||||
|
|
||||||
this.compiler = compiler;
|
|
||||||
this.directiveMetadataReader = directiveMetadataReader;
|
|
||||||
this.viewFactory = viewFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
load(type:Type, location:PrivateComponentLocation) {
|
|
||||||
var annotation = this.directiveMetadataReader.read(type).annotation;
|
|
||||||
|
|
||||||
if (!(annotation instanceof Component)) {
|
|
||||||
throw new BaseException(`Could not load '${stringify(type)}' because it is not a component.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.compiler.compile(type).then((componentProtoView) => {
|
|
||||||
location.createComponent(
|
|
||||||
this.viewFactory,
|
|
||||||
type, annotation,
|
|
||||||
componentProtoView
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
import {Directive} from 'angular2/src/core/annotations/annotations'
|
|
||||||
import * as viewModule from './view';
|
|
||||||
import * as eiModule from './element_injector';
|
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
|
||||||
import {Type} from 'angular2/src/facade/lang';
|
|
||||||
import * as vfModule from './view_factory';
|
|
||||||
|
|
||||||
export class PrivateComponentLocation {
|
|
||||||
_elementInjector:eiModule.ElementInjector;
|
|
||||||
_view:viewModule.View;
|
|
||||||
|
|
||||||
constructor(elementInjector:eiModule.ElementInjector, view:viewModule.View){
|
|
||||||
this._elementInjector = elementInjector;
|
|
||||||
this._view = view;
|
|
||||||
}
|
|
||||||
|
|
||||||
createComponent(viewFactory: vfModule.ViewFactory, type:Type, annotation:Directive, componentProtoView:viewModule.ProtoView) {
|
|
||||||
var context = this._elementInjector.createPrivateComponent(type, annotation);
|
|
||||||
|
|
||||||
var view = viewFactory.getView(componentProtoView);
|
|
||||||
view.hydrate(this._elementInjector.getShadowDomAppInjector(), this._elementInjector, context, null);
|
|
||||||
|
|
||||||
this._view.proto.renderer.setDynamicComponentView(
|
|
||||||
this._view.render, this._elementInjector.getBoundElementIndex(), view.render
|
|
||||||
);
|
|
||||||
ListWrapper.push(this._view.componentChildViews, view);
|
|
||||||
this._view.changeDetector.addChild(view.changeDetector);
|
|
||||||
}
|
|
||||||
}
|
|
16
modules/angular2/src/core/compiler/view.js
vendored
16
modules/angular2/src/core/compiler/view.js
vendored
@ -28,7 +28,18 @@ export class View {
|
|||||||
viewContainers: List<ViewContainer>;
|
viewContainers: List<ViewContainer>;
|
||||||
preBuiltObjects: List<PreBuiltObjects>;
|
preBuiltObjects: List<PreBuiltObjects>;
|
||||||
proto: ProtoView;
|
proto: ProtoView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The context against which data-binding expressions in this view are evaluated against.
|
||||||
|
* This is always a component instance.
|
||||||
|
*/
|
||||||
context: any;
|
context: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variables, local to this view, that can be used in binding expressions (in addition to the
|
||||||
|
* context). This is used for thing like `<video #player>` or
|
||||||
|
* `<li template="for #item of items">`, where "player" and "item" are locals, respectively.
|
||||||
|
*/
|
||||||
locals:Locals;
|
locals:Locals;
|
||||||
|
|
||||||
constructor(proto:ProtoView, protoLocals:Map) {
|
constructor(proto:ProtoView, protoLocals:Map) {
|
||||||
@ -244,6 +255,11 @@ export class View {
|
|||||||
return elementInjector.getDirectiveAtIndex(directive.directiveIndex);
|
return elementInjector.getDirectiveAtIndex(directive.directiveIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addComponentChildView(view:View) {
|
||||||
|
ListWrapper.push(this.componentChildViews, view);
|
||||||
|
this.changeDetector.addShadowDomChild(view.changeDetector);
|
||||||
|
}
|
||||||
|
|
||||||
// implementation of EventDispatcher#dispatchEvent
|
// implementation of EventDispatcher#dispatchEvent
|
||||||
dispatchEvent(
|
dispatchEvent(
|
||||||
elementIndex:number, eventName:string, locals:Map<string, any>
|
elementIndex:number, eventName:string, locals:Map<string, any>
|
||||||
|
@ -7,6 +7,7 @@ import {ExceptionHandler} from 'angular2/src/core/exception_handler';
|
|||||||
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
|
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
|
||||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
|
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
|
import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
|
||||||
import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
|
import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
|
||||||
import {XHR} from 'angular2/src/services/xhr';
|
import {XHR} from 'angular2/src/services/xhr';
|
||||||
@ -15,7 +16,6 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
|
|||||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||||
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
|
||||||
|
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ function _getAppBindings() {
|
|||||||
bind(TemplateResolver).toClass(MockTemplateResolver),
|
bind(TemplateResolver).toClass(MockTemplateResolver),
|
||||||
bind(ChangeDetection).toValue(dynamicChangeDetection),
|
bind(ChangeDetection).toValue(dynamicChangeDetection),
|
||||||
TemplateLoader,
|
TemplateLoader,
|
||||||
PrivateComponentLoader,
|
DynamicComponentLoader,
|
||||||
DirectiveMetadataReader,
|
DirectiveMetadataReader,
|
||||||
Parser,
|
Parser,
|
||||||
Lexer,
|
Lexer,
|
||||||
|
@ -98,9 +98,8 @@ export function main() {
|
|||||||
it('should throw if bootstrapped Directive is not a Component', inject([AsyncTestCompleter], (async) => {
|
it('should throw if bootstrapped Directive is not a Component', inject([AsyncTestCompleter], (async) => {
|
||||||
var injectorPromise = bootstrap(HelloRootDirectiveIsNotCmp, testBindings, (e,t) => {throw e;});
|
var injectorPromise = bootstrap(HelloRootDirectiveIsNotCmp, testBindings, (e,t) => {throw e;});
|
||||||
PromiseWrapper.then(injectorPromise, null, (reason) => {
|
PromiseWrapper.then(injectorPromise, null, (reason) => {
|
||||||
expect(reason.message).toContain('Only Components can be bootstrapped; ' +
|
expect(reason.message).toContain(`Could not load 'HelloRootDirectiveIsNotCmp' because it is not a component.`);
|
||||||
'Directive of HelloRootDirectiveIsNotCmp is not a Component');
|
async.done();
|
||||||
async.done();
|
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -137,7 +136,6 @@ export function main() {
|
|||||||
it('should display hello world', inject([AsyncTestCompleter], (async) => {
|
it('should display hello world', inject([AsyncTestCompleter], (async) => {
|
||||||
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
|
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
|
||||||
injectorPromise.then((injector) => {
|
injectorPromise.then((injector) => {
|
||||||
|
|
||||||
expect(injector.get(appElementToken)).toHaveText('hello world!');
|
expect(injector.get(appElementToken)).toHaveText('hello world!');
|
||||||
async.done();
|
async.done();
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/test_lib';
|
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/test_lib';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
import {DynamicComponentLoader, DirectiveRef} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
import {Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
|
import {Decorator, Viewport} from 'angular2/src/core/annotations/annotations';
|
||||||
|
|
||||||
@Decorator({selector: 'someDecorator'})
|
@Decorator({selector: 'someDecorator'})
|
||||||
@ -10,23 +10,26 @@ class SomeDecorator {}
|
|||||||
class SomeViewport {}
|
class SomeViewport {}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe("PrivateComponentLoader", () => {
|
describe("DynamicComponentLoader", () => {
|
||||||
var loader;
|
var loader;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
loader = new PrivateComponentLoader(null, new DirectiveMetadataReader(), null);
|
loader = new DynamicComponentLoader(null, new DirectiveMetadataReader(), null, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Load errors', () => {
|
describe("loadIntoExistingLocation", () => {
|
||||||
it('should throw when trying to load a decorator', () => {
|
describe('Load errors', () => {
|
||||||
expect(() => loader.load(SomeDecorator, null))
|
it('should throw when trying to load a decorator', () => {
|
||||||
|
expect(() => loader.loadIntoExistingLocation(SomeDecorator, null))
|
||||||
.toThrowError("Could not load 'SomeDecorator' because it is not a component.");
|
.toThrowError("Could not load 'SomeDecorator' because it is not a component.");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when trying to load a viewport', () => {
|
it('should throw when trying to load a viewport', () => {
|
||||||
expect(() => loader.load(SomeViewport, null))
|
expect(() => loader.loadIntoExistingLocation(SomeViewport, null))
|
||||||
.toThrowError("Could not load 'SomeViewport' because it is not a component.");
|
.toThrowError("Could not load 'SomeViewport' because it is not a component.");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -621,58 +621,76 @@ export function main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("createPrivateComponent", () => {
|
describe("dynamicallyCreateComponent", () => {
|
||||||
it("should create a private component", () => {
|
it("should create a component dynamically", () => {
|
||||||
var inj = injector([]);
|
var inj = injector([]);
|
||||||
inj.createPrivateComponent(SimpleDirective, null);
|
inj.dynamicallyCreateComponent(SimpleDirective, null, null);
|
||||||
expect(inj.getPrivateComponent()).toBeAnInstanceOf(SimpleDirective);
|
expect(inj.getDynamicallyLoadedComponent()).toBeAnInstanceOf(SimpleDirective);
|
||||||
|
expect(inj.get(SimpleDirective)).toBeAnInstanceOf(SimpleDirective);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inject parent dependencies into the private component", () => {
|
it("should inject parent dependencies into the dynamically-loaded component", () => {
|
||||||
var inj = parentChildInjectors([SimpleDirective], []);
|
var inj = parentChildInjectors([SimpleDirective], []);
|
||||||
inj.createPrivateComponent(NeedDirectiveFromAncestor, null);
|
inj.dynamicallyCreateComponent(NeedDirectiveFromAncestor, null, null);
|
||||||
expect(inj.getPrivateComponent()).toBeAnInstanceOf(NeedDirectiveFromAncestor);
|
expect(inj.getDynamicallyLoadedComponent()).toBeAnInstanceOf(NeedDirectiveFromAncestor);
|
||||||
expect(inj.getPrivateComponent().dependency).toBeAnInstanceOf(SimpleDirective);
|
expect(inj.getDynamicallyLoadedComponent().dependency).toBeAnInstanceOf(SimpleDirective);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not inject the proxy component into the children of the private component", () => {
|
it("should not inject the proxy component into the children of the dynamically-loaded component", () => {
|
||||||
var injWithPrivateComponent = injector([SimpleDirective]);
|
var injWithDynamicallyLoadedComponent = injector([SimpleDirective]);
|
||||||
injWithPrivateComponent.createPrivateComponent(SomeOtherDirective, null);
|
injWithDynamicallyLoadedComponent.dynamicallyCreateComponent(SomeOtherDirective, null, null);
|
||||||
|
|
||||||
var shadowDomProtoInjector = new ProtoElementInjector(null, 0, [NeedDirectiveFromAncestor], false);
|
var shadowDomProtoInjector = new ProtoElementInjector(null, 0, [NeedDirectiveFromAncestor], false);
|
||||||
var shadowDomInj = shadowDomProtoInjector.instantiate(null);
|
var shadowDomInj = shadowDomProtoInjector.instantiate(null);
|
||||||
|
|
||||||
expect(() => shadowDomInj.instantiateDirectives(appInjector, injWithPrivateComponent, null, defaultPreBuiltObjects)).
|
expect(() =>
|
||||||
|
shadowDomInj.instantiateDirectives(appInjector, injWithDynamicallyLoadedComponent,null, defaultPreBuiltObjects)).
|
||||||
toThrowError(new RegExp("No provider for SimpleDirective"));
|
toThrowError(new RegExp("No provider for SimpleDirective"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inject the private component into the children of the private component", () => {
|
it("should not inject the dynamically-loaded component into directives on the same element", () => {
|
||||||
var injWithPrivateComponent = injector([]);
|
var proto = new ProtoElementInjector(null, 0, [NeedsDirective], false);
|
||||||
injWithPrivateComponent.createPrivateComponent(SimpleDirective, null);
|
var inj = proto.instantiate(null);
|
||||||
|
inj.dynamicallyCreateComponent(SimpleDirective, null, null);
|
||||||
|
|
||||||
|
expect(() => inj.instantiateDirectives(null, null, null, null)).toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should inject the dynamically-loaded component into the children of the dynamically-loaded component", () => {
|
||||||
|
var injWithDynamicallyLoadedComponent = injector([]);
|
||||||
|
injWithDynamicallyLoadedComponent.dynamicallyCreateComponent(SimpleDirective, null, null);
|
||||||
|
|
||||||
var shadowDomProtoInjector = new ProtoElementInjector(null, 0, [NeedDirectiveFromAncestor], false);
|
var shadowDomProtoInjector = new ProtoElementInjector(null, 0, [NeedDirectiveFromAncestor], false);
|
||||||
var shadowDomInjector = shadowDomProtoInjector.instantiate(null);
|
var shadowDomInjector = shadowDomProtoInjector.instantiate(null);
|
||||||
shadowDomInjector.instantiateDirectives(appInjector, injWithPrivateComponent, null, defaultPreBuiltObjects);
|
shadowDomInjector.instantiateDirectives(appInjector, injWithDynamicallyLoadedComponent, null, defaultPreBuiltObjects);
|
||||||
|
|
||||||
expect(shadowDomInjector.get(NeedDirectiveFromAncestor)).toBeAnInstanceOf(NeedDirectiveFromAncestor);
|
expect(shadowDomInjector.get(NeedDirectiveFromAncestor)).toBeAnInstanceOf(NeedDirectiveFromAncestor);
|
||||||
expect(shadowDomInjector.get(NeedDirectiveFromAncestor).dependency).toBeAnInstanceOf(SimpleDirective);
|
expect(shadowDomInjector.get(NeedDirectiveFromAncestor).dependency).toBeAnInstanceOf(SimpleDirective);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should support rehydrating the private component", () => {
|
it("should remove the dynamically-loaded component when dehydrating", () => {
|
||||||
var inj = injector([]);
|
var inj = injector([]);
|
||||||
inj.createPrivateComponent(
|
inj.dynamicallyCreateComponent(
|
||||||
DirectiveWithDestroy,
|
DirectiveWithDestroy,
|
||||||
new DummyDirective({lifecycle: [onDestroy]}));
|
new DummyDirective({lifecycle: [onDestroy]}),
|
||||||
var dir = inj.getPrivateComponent();
|
null);
|
||||||
|
var dir = inj.getDynamicallyLoadedComponent();
|
||||||
|
|
||||||
inj.clearDirectives();
|
inj.clearDirectives();
|
||||||
|
|
||||||
expect(inj.getPrivateComponent()).toBe(null);
|
expect(inj.getDynamicallyLoadedComponent()).toBe(null);
|
||||||
expect(dir.onDestroyCounter).toBe(1);
|
expect(dir.onDestroyCounter).toBe(1);
|
||||||
|
|
||||||
inj.instantiateDirectives(null, null, null, null);
|
inj.instantiateDirectives(null, null, null, null);
|
||||||
|
|
||||||
expect(inj.getPrivateComponent()).not.toBe(null);
|
expect(inj.getDynamicallyLoadedComponent()).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should inject services of the dynamically-loaded component", () => {
|
||||||
|
var inj = injector([]);
|
||||||
|
var appInjector = new Injector([bind("service").toValue("Service")]);
|
||||||
|
inj.dynamicallyCreateComponent(NeedsService, null, appInjector);
|
||||||
|
expect(inj.getDynamicallyLoadedComponent().service).toEqual("Service");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -24,13 +24,12 @@ import {Injector, bind} from 'angular2/di';
|
|||||||
import {dynamicChangeDetection,
|
import {dynamicChangeDetection,
|
||||||
ChangeDetection, DynamicChangeDetection, Pipe, PipeRegistry, BindingPropagationConfig, ON_PUSH} from 'angular2/change_detection';
|
ChangeDetection, DynamicChangeDetection, Pipe, PipeRegistry, BindingPropagationConfig, ON_PUSH} from 'angular2/change_detection';
|
||||||
|
|
||||||
import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location';
|
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
|
||||||
|
|
||||||
import {Decorator, Component, Viewport, DynamicComponent} from 'angular2/src/core/annotations/annotations';
|
import {Decorator, Component, Viewport, DynamicComponent} from 'angular2/src/core/annotations/annotations';
|
||||||
import {Template} from 'angular2/src/core/annotations/template';
|
import {Template} from 'angular2/src/core/annotations/template';
|
||||||
import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
|
import {Parent, Ancestor} from 'angular2/src/core/annotations/visibility';
|
||||||
import {EventEmitter, Attribute} from 'angular2/src/core/annotations/di';
|
import {EventEmitter, Attribute} from 'angular2/src/core/annotations/di';
|
||||||
|
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
|
import {DirectiveRef} from 'angular2/src/core/compiler/element_injector';
|
||||||
|
|
||||||
import {If} from 'angular2/src/directives/if';
|
import {If} from 'angular2/src/directives/if';
|
||||||
|
|
||||||
@ -544,23 +543,40 @@ export function main() {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should support dynamic components', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
describe("dynamic components", () => {
|
||||||
tb.overrideTemplate(MyComp, new Template({
|
it('should support loading components dynamically', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
inline: '<dynamic-comp #dynamic></dynamic-comp>',
|
tb.overrideTemplate(MyComp, new Template({
|
||||||
directives: [DynamicComp]
|
inline: '<dynamic-comp #dynamic></dynamic-comp>',
|
||||||
}));
|
directives: [DynamicComp]
|
||||||
tb.createView(MyComp, {context: ctx}).then((view) => {
|
}));
|
||||||
|
|
||||||
var dynamicComponent = view.rawView.locals.get("dynamic");
|
tb.createView(MyComp).then((view) => {
|
||||||
expect(dynamicComponent).toBeAnInstanceOf(DynamicComp);
|
var dynamicComponent = view.rawView.locals.get("dynamic");
|
||||||
|
expect(dynamicComponent).toBeAnInstanceOf(DynamicComp);
|
||||||
|
|
||||||
dynamicComponent.done.then((_) => {
|
dynamicComponent.done.then((_) => {
|
||||||
view.detectChanges();
|
view.detectChanges();
|
||||||
expect(view.rootNodes).toHaveText('hello');
|
expect(view.rootNodes).toHaveText('hello');
|
||||||
async.done();
|
async.done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
}));
|
|
||||||
|
it('should inject dependencies of the dynamically-loaded component', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
|
tb.overrideTemplate(MyComp, new Template({
|
||||||
|
inline: '<dynamic-comp #dynamic></dynamic-comp>',
|
||||||
|
directives: [DynamicComp]
|
||||||
|
}));
|
||||||
|
|
||||||
|
tb.createView(MyComp).then((view) => {
|
||||||
|
var dynamicComponent = view.rawView.locals.get("dynamic");
|
||||||
|
dynamicComponent.done.then((ref) => {
|
||||||
|
expect(ref.instance.dynamicallyCreatedComponentService).toBeAnInstanceOf(DynamicallyCreatedComponentService);
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
it('should support static attributes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
it('should support static attributes', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
tb.overrideTemplate(MyComp, new Template({
|
tb.overrideTemplate(MyComp, new Template({
|
||||||
@ -568,7 +584,6 @@ export function main() {
|
|||||||
directives: [NeedsAttribute]
|
directives: [NeedsAttribute]
|
||||||
}));
|
}));
|
||||||
tb.createView(MyComp, {context: ctx}).then((view) => {
|
tb.createView(MyComp, {context: ctx}).then((view) => {
|
||||||
|
|
||||||
var injector = view.rawView.elementInjectors[0];
|
var injector = view.rawView.elementInjectors[0];
|
||||||
var needsAttribute = injector.get(NeedsAttribute);
|
var needsAttribute = injector.get(NeedsAttribute);
|
||||||
expect(needsAttribute.typeAttribute).toEqual('text');
|
expect(needsAttribute.typeAttribute).toEqual('text');
|
||||||
@ -643,27 +658,32 @@ export function main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DynamicallyCreatedComponentService {
|
||||||
|
}
|
||||||
|
|
||||||
@DynamicComponent({
|
@DynamicComponent({
|
||||||
selector: 'dynamic-comp'
|
selector: 'dynamic-comp'
|
||||||
})
|
})
|
||||||
class DynamicComp {
|
class DynamicComp {
|
||||||
done;
|
done;
|
||||||
constructor(loader:PrivateComponentLoader, location:PrivateComponentLocation) {
|
constructor(loader:DynamicComponentLoader, self:DirectiveRef) {
|
||||||
this.done = loader.load(HelloCmp, location);
|
this.done = loader.loadIntoExistingLocation(DynamicallyCreatedCmp, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'hello-cmp'
|
selector: 'hello-cmp',
|
||||||
|
services: [DynamicallyCreatedComponentService]
|
||||||
})
|
})
|
||||||
@Template({
|
@Template({
|
||||||
inline: "{{greeting}}"
|
inline: "{{greeting}}"
|
||||||
})
|
})
|
||||||
class HelloCmp {
|
class DynamicallyCreatedCmp {
|
||||||
greeting:string;
|
greeting:string;
|
||||||
constructor() {
|
dynamicallyCreatedComponentService:DynamicallyCreatedComponentService;
|
||||||
|
constructor(a:DynamicallyCreatedComponentService) {
|
||||||
this.greeting = "hello";
|
this.greeting = "hello";
|
||||||
|
this.dynamicallyCreatedComponentService = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
|
|||||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
||||||
|
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
@ -290,10 +290,10 @@ function setupReflector() {
|
|||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
reflector.registerType(PrivateComponentLoader, {
|
reflector.registerType(DynamicComponentLoader, {
|
||||||
"factory": (compiler, reader, viewFactory) =>
|
"factory": (compiler, reader, renderer, viewFactory) =>
|
||||||
new PrivateComponentLoader(compiler, reader, viewFactory),
|
new DynamicComponentLoader(compiler, reader, renderer, viewFactory),
|
||||||
"parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
|
"parameters": [[Compiler], [DirectiveMetadataReader], [Renderer], [ViewFactory]],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
|
|||||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
||||||
|
|
||||||
import {If, For} from 'angular2/directives';
|
import {If, For} from 'angular2/directives';
|
||||||
@ -316,10 +316,11 @@ export function setupReflectorForAngular() {
|
|||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
reflector.registerType(PrivateComponentLoader, {
|
|
||||||
"factory": (compiler, reader, viewFactory) =>
|
reflector.registerType(DynamicComponentLoader, {
|
||||||
new PrivateComponentLoader(compiler, reader, viewFactory),
|
"factory": (compiler, reader, renderer, viewFactory) =>
|
||||||
"parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
|
new DynamicComponentLoader(compiler, reader, renderer, viewFactory),
|
||||||
|
"parameters": [[Compiler], [DirectiveMetadataReader], [Renderer], [ViewFactory]],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import {UrlResolver} from 'angular2/src/services/url_resolver';
|
|||||||
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
||||||
|
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
@ -205,13 +205,13 @@ function setupReflector() {
|
|||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
reflector.registerType(PrivateComponentLoader, {
|
reflector.registerType(DynamicComponentLoader, {
|
||||||
"factory": (compiler, reader, viewFactory) =>
|
"factory": (compiler, reader, renderer, viewFactory) =>
|
||||||
new PrivateComponentLoader(compiler, reader, viewFactory),
|
new DynamicComponentLoader(compiler, reader, renderer, viewFactory),
|
||||||
"parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
|
"parameters": [[Compiler], [DirectiveMetadataReader], [Renderer], [ViewFactory]],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
reflector.registerType(DirectDomRenderer, {
|
reflector.registerType(DirectDomRenderer, {
|
||||||
"factory": (renderCompiler, renderViewFactory, shadowDomStrategy) =>
|
"factory": (renderCompiler, renderViewFactory, shadowDomStrategy) =>
|
||||||
new DirectDomRenderer(renderCompiler, renderViewFactory, shadowDomStrategy),
|
new DirectDomRenderer(renderCompiler, renderViewFactory, shadowDomStrategy),
|
||||||
|
@ -23,7 +23,7 @@ import {Injectable} from 'angular2/di';
|
|||||||
// Expressions in the template (like {{greeting}}) are evaluated in the
|
// Expressions in the template (like {{greeting}}) are evaluated in the
|
||||||
// context of the HelloCmp class below.
|
// context of the HelloCmp class below.
|
||||||
inline: `<div class="greeting">{{greeting}} <span red>world</span>!</div>
|
inline: `<div class="greeting">{{greeting}} <span red>world</span>!</div>
|
||||||
<button class="changeButton" (click)="changeGreeting()">change greeting</button>`,
|
<button class="changeButton" (click)="changeGreeting()">change greeting</button><content></content>`,
|
||||||
// All directives used in the template need to be specified. This allows for
|
// All directives used in the template need to be specified. This allows for
|
||||||
// modularity (RedDec can only be used in this template)
|
// modularity (RedDec can only be used in this template)
|
||||||
// and better tooling (the template can be invalidated if the attribute is
|
// and better tooling (the template can be invalidated if the attribute is
|
||||||
|
@ -19,7 +19,7 @@ import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_res
|
|||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
import {StyleInliner} from 'angular2/src/render/dom/shadow_dom/style_inliner';
|
||||||
import {EventManager} from 'angular2/src/render/dom/events/event_manager';
|
import {EventManager} from 'angular2/src/render/dom/events/event_manager';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||||
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
||||||
|
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
@ -173,10 +173,57 @@ function setup() {
|
|||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
reflector.registerType(PrivateComponentLoader, {
|
reflector.registerType(DynamicComponentLoader, {
|
||||||
"factory": (compiler, reader, viewFactory) =>
|
"factory": (compiler, reader, renderer, viewFactory) =>
|
||||||
new PrivateComponentLoader(compiler, reader, viewFactory),
|
new DynamicComponentLoader(compiler, reader, renderer, viewFactory),
|
||||||
"parameters": [[Compiler], [DirectiveMetadataReader], [ViewFactory]],
|
"parameters": [[Compiler], [DirectiveMetadataReader], [Renderer], [ViewFactory]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(DirectDomRenderer, {
|
||||||
|
"factory": (renderCompiler, renderViewFactory, shadowDomStrategy) =>
|
||||||
|
new DirectDomRenderer(renderCompiler, renderViewFactory, shadowDomStrategy),
|
||||||
|
"parameters": [[rc.Compiler], [rvf.ViewFactory], [ShadowDomStrategy]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(rc.DefaultCompiler, {
|
||||||
|
"factory": (parser, shadowDomStrategy, templateLoader) =>
|
||||||
|
new rc.DefaultCompiler(parser, shadowDomStrategy, templateLoader),
|
||||||
|
"parameters": [[Parser], [ShadowDomStrategy], [TemplateLoader]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(rvf.ViewFactory, {
|
||||||
|
"factory": (capacity, eventManager, shadowDomStrategy) =>
|
||||||
|
new rvf.ViewFactory(capacity, eventManager, shadowDomStrategy),
|
||||||
|
"parameters": [[new Inject(rvf.VIEW_POOL_CAPACITY)], [EventManager], [ShadowDomStrategy]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(rvf.VIEW_POOL_CAPACITY, {
|
||||||
|
"factory": () => 100000,
|
||||||
|
"parameters": [],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(ProtoViewFactory, {
|
||||||
|
"factory": (changeDetection, renderer) =>
|
||||||
|
new ProtoViewFactory(changeDetection, renderer),
|
||||||
|
"parameters": [[ChangeDetection], [Renderer]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(ViewFactory, {
|
||||||
|
"factory": (capacity) =>
|
||||||
|
new ViewFactory(capacity),
|
||||||
|
"parameters": [[new Inject(VIEW_POOL_CAPACITY)]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
|
reflector.registerType(VIEW_POOL_CAPACITY, {
|
||||||
|
"factory": () => 100000,
|
||||||
|
"parameters": [],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user