feat(ElementInjector): add NgElement
This commit is contained in:
parent
ac8351b7bc
commit
d7208b8429
@ -10,8 +10,8 @@ export function run () {
|
|||||||
var bindings = [A, B, C];
|
var bindings = [A, B, C];
|
||||||
var proto = new ProtoElementInjector(null, 0, bindings);
|
var proto = new ProtoElementInjector(null, 0, bindings);
|
||||||
for (var i = 0; i < ITERATIONS; ++i) {
|
for (var i = 0; i < ITERATIONS; ++i) {
|
||||||
var ei = proto.instantiate(null,null,null);
|
var ei = proto.instantiate(null, null);
|
||||||
ei.instantiateDirectives(appInjector, null);
|
ei.instantiateDirectives(appInjector, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ export function run () {
|
|||||||
|
|
||||||
var proto = new ProtoElementInjector(null, 0, bindings);
|
var proto = new ProtoElementInjector(null, 0, bindings);
|
||||||
for (var i = 0; i < ITERATIONS; ++i) {
|
for (var i = 0; i < ITERATIONS; ++i) {
|
||||||
var ei = proto.instantiate(null,null,null);
|
var ei = proto.instantiate(null,null);
|
||||||
ei.instantiateDirectives(appInjector, null);
|
ei.instantiateDirectives(appInjector, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@ export function run () {
|
|||||||
|
|
||||||
var bindings = [A, B, C];
|
var bindings = [A, B, C];
|
||||||
var proto = new ProtoElementInjector(null, 0, bindings);
|
var proto = new ProtoElementInjector(null, 0, bindings);
|
||||||
var ei = proto.instantiate(null,null,null);
|
var ei = proto.instantiate(null,null);
|
||||||
|
|
||||||
for (var i = 0; i < ITERATIONS; ++i) {
|
for (var i = 0; i < ITERATIONS; ++i) {
|
||||||
ei.clearDirectives();
|
ei.clearDirectives();
|
||||||
ei.instantiateDirectives(appInjector, null);
|
ei.instantiateDirectives(appInjector, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import {Parent, Ancestor} from 'core/annotations/visibility';
|
|||||||
import {StaticKeys} from './static_keys';
|
import {StaticKeys} from './static_keys';
|
||||||
// Comment out as dartanalyzer does not look into @FIELD
|
// Comment out as dartanalyzer does not look into @FIELD
|
||||||
// import {View} from './view';
|
// import {View} from './view';
|
||||||
|
import {NgElement} from 'core/dom/element';
|
||||||
|
|
||||||
var _MAX_DIRECTIVE_CONSTRUCTION_COUNTER = 10;
|
var _MAX_DIRECTIVE_CONSTRUCTION_COUNTER = 10;
|
||||||
|
|
||||||
@ -75,6 +76,15 @@ class DirectiveDependency extends Dependency {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PreBuiltObjects {
|
||||||
|
@FIELD('final view:View')
|
||||||
|
@FIELD('final element:NgElement')
|
||||||
|
constructor(view, element:NgElement) {
|
||||||
|
this.view = view;
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
Difference between di.Injector and ElementInjector
|
Difference between di.Injector and ElementInjector
|
||||||
@ -152,8 +162,8 @@ export class ProtoElementInjector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiate(parent:ElementInjector, host:ElementInjector, view):ElementInjector {
|
instantiate(parent:ElementInjector, host:ElementInjector):ElementInjector {
|
||||||
return new ElementInjector(this, parent, host, view);
|
return new ElementInjector(this, parent, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBinding(bindingOrType) {
|
_createBinding(bindingOrType) {
|
||||||
@ -170,49 +180,6 @@ export class ProtoElementInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ElementInjector extends TreeNode {
|
export class ElementInjector extends TreeNode {
|
||||||
/*
|
|
||||||
_protoInjector:ProtoElementInjector;
|
|
||||||
injector:Injector;
|
|
||||||
_parent:ElementInjector;
|
|
||||||
_next:ElementInjector;
|
|
||||||
_prev:ElementInjector;
|
|
||||||
_head:ElementInjector;
|
|
||||||
_tail:ElementInjector;
|
|
||||||
|
|
||||||
|
|
||||||
// For performance reasons the Injector only supports 10 directives per element.
|
|
||||||
// NOTE: linear search over fields is faster than HashMap lookup.
|
|
||||||
_cObj; // Component only
|
|
||||||
_obj0;
|
|
||||||
_obj1;
|
|
||||||
_obj2;
|
|
||||||
_obj3;
|
|
||||||
_obj4;
|
|
||||||
_obj5;
|
|
||||||
_obj6;
|
|
||||||
_obj7;
|
|
||||||
_obj8;
|
|
||||||
_obj9;
|
|
||||||
|
|
||||||
element:Element;
|
|
||||||
ngElement:NgElement;
|
|
||||||
shadowRoot:ShadowRoot;
|
|
||||||
elementProbe:ElementProbe;
|
|
||||||
view:View;
|
|
||||||
viewPort:ViewPort;
|
|
||||||
viewFactory:ViewFactory;
|
|
||||||
animate:Animate;
|
|
||||||
destinationLightDom:DestinationLightDom;
|
|
||||||
sourceLightDom:SourceLightDom;
|
|
||||||
|
|
||||||
|
|
||||||
// For performance reasons the Injector only supports 2 [Query] per element.
|
|
||||||
// NOTE: linear search over fields is faster than HashMap lookup.
|
|
||||||
_query0:Query;
|
|
||||||
_query1:Query;
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
@FIELD('_proto:ProtoElementInjector')
|
@FIELD('_proto:ProtoElementInjector')
|
||||||
@FIELD('_lightDomAppInjector:Injector')
|
@FIELD('_lightDomAppInjector:Injector')
|
||||||
@FIELD('_shadowDomAppInjector:Injector')
|
@FIELD('_shadowDomAppInjector:Injector')
|
||||||
@ -228,7 +195,7 @@ export class ElementInjector extends TreeNode {
|
|||||||
@FIELD('_obj8:Object')
|
@FIELD('_obj8:Object')
|
||||||
@FIELD('_obj9:Object')
|
@FIELD('_obj9:Object')
|
||||||
@FIELD('_view:View')
|
@FIELD('_view:View')
|
||||||
constructor(proto:ProtoElementInjector, parent:ElementInjector, host:ElementInjector, view) {
|
constructor(proto:ProtoElementInjector, parent:ElementInjector, host:ElementInjector) {
|
||||||
super(parent);
|
super(parent);
|
||||||
if (isPresent(parent) && isPresent(host)) {
|
if (isPresent(parent) && isPresent(host)) {
|
||||||
throw new BaseException('Only either parent or host is allowed');
|
throw new BaseException('Only either parent or host is allowed');
|
||||||
@ -241,9 +208,9 @@ export class ElementInjector extends TreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._proto = proto;
|
this._proto = proto;
|
||||||
this._view = view;
|
|
||||||
|
|
||||||
//we cannot call clearDirectives because fields won't be detected
|
//we cannot call clearDirectives because fields won't be detected
|
||||||
|
this._preBuiltObjects = null;
|
||||||
this._lightDomAppInjector = null;
|
this._lightDomAppInjector = null;
|
||||||
this._shadowDomAppInjector = null;
|
this._shadowDomAppInjector = null;
|
||||||
this._obj0 = null;
|
this._obj0 = null;
|
||||||
@ -260,6 +227,7 @@ export class ElementInjector extends TreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearDirectives() {
|
clearDirectives() {
|
||||||
|
this._preBuiltObjects = null;
|
||||||
this._lightDomAppInjector = null;
|
this._lightDomAppInjector = null;
|
||||||
this._shadowDomAppInjector = null;
|
this._shadowDomAppInjector = null;
|
||||||
|
|
||||||
@ -276,16 +244,14 @@ export class ElementInjector extends TreeNode {
|
|||||||
this._constructionCounter = 0;
|
this._constructionCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiateDirectives(lightDomAppInjector:Injector, shadowDomAppInjector:Injector) {
|
instantiateDirectives(lightDomAppInjector:Injector, shadowDomAppInjector:Injector, preBuiltObjects:PreBuiltObjects) {
|
||||||
var p = this._proto;
|
this._checkShadowDomAppInjector(shadowDomAppInjector);
|
||||||
if (this._proto._binding0IsComponent && isBlank(shadowDomAppInjector)) {
|
|
||||||
throw new BaseException('A shadowDomAppInjector is required as this ElementInjector contains a component');
|
this._preBuiltObjects = preBuiltObjects;
|
||||||
} else if (!this._proto._binding0IsComponent && isPresent(shadowDomAppInjector)) {
|
|
||||||
throw new BaseException('No shadowDomAppInjector allowed as there is not component stored in this ElementInjector');
|
|
||||||
}
|
|
||||||
this._lightDomAppInjector = lightDomAppInjector;
|
this._lightDomAppInjector = lightDomAppInjector;
|
||||||
this._shadowDomAppInjector = shadowDomAppInjector;
|
this._shadowDomAppInjector = shadowDomAppInjector;
|
||||||
|
|
||||||
|
var p = this._proto;
|
||||||
if (isPresent(p._keyId0)) this._getDirectiveByKeyId(p._keyId0);
|
if (isPresent(p._keyId0)) this._getDirectiveByKeyId(p._keyId0);
|
||||||
if (isPresent(p._keyId1)) this._getDirectiveByKeyId(p._keyId1);
|
if (isPresent(p._keyId1)) this._getDirectiveByKeyId(p._keyId1);
|
||||||
if (isPresent(p._keyId2)) this._getDirectiveByKeyId(p._keyId2);
|
if (isPresent(p._keyId2)) this._getDirectiveByKeyId(p._keyId2);
|
||||||
@ -298,6 +264,14 @@ export class ElementInjector extends TreeNode {
|
|||||||
if (isPresent(p._keyId9)) this._getDirectiveByKeyId(p._keyId9);
|
if (isPresent(p._keyId9)) this._getDirectiveByKeyId(p._keyId9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_checkShadowDomAppInjector(shadowDomAppInjector:Injector) {
|
||||||
|
if (this._proto._binding0IsComponent && isBlank(shadowDomAppInjector)) {
|
||||||
|
throw new BaseException('A shadowDomAppInjector is required as this ElementInjector contains a component');
|
||||||
|
} else if (!this._proto._binding0IsComponent && isPresent(shadowDomAppInjector)) {
|
||||||
|
throw new BaseException('No shadowDomAppInjector allowed as there is not component stored in this ElementInjector');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get(token) {
|
get(token) {
|
||||||
return this._getByKey(Key.get(token), 0, null);
|
return this._getByKey(Key.get(token), 0, null);
|
||||||
}
|
}
|
||||||
@ -370,7 +344,7 @@ export class ElementInjector extends TreeNode {
|
|||||||
* This would allows to do the lookup more efficiently.
|
* This would allows to do the lookup more efficiently.
|
||||||
*
|
*
|
||||||
* for example
|
* for example
|
||||||
* we would lookup special objects only when metadata = 'special'
|
* we would lookup pre built objects only when metadata = 'preBuilt'
|
||||||
* we would lookup directives only when metadata = 'directive'
|
* we would lookup directives only when metadata = 'directive'
|
||||||
*
|
*
|
||||||
* Write benchmarks before doing this optimization.
|
* Write benchmarks before doing this optimization.
|
||||||
@ -384,8 +358,8 @@ export class ElementInjector extends TreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (ei != null && depth >= 0) {
|
while (ei != null && depth >= 0) {
|
||||||
var specObj = ei._getSpecialObjectByKeyId(key.id);
|
var preBuiltObj = ei._getPreBuiltObjectByKeyId(key.id);
|
||||||
if (specObj !== _undefined) return specObj;
|
if (preBuiltObj !== _undefined) return preBuiltObj;
|
||||||
|
|
||||||
var dir = ei._getDirectiveByKeyId(key.id);
|
var dir = ei._getDirectiveByKeyId(key.id);
|
||||||
if (dir !== _undefined) return dir;
|
if (dir !== _undefined) return dir;
|
||||||
@ -397,13 +371,15 @@ export class ElementInjector extends TreeNode {
|
|||||||
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 {
|
} else {
|
||||||
var appInjector;
|
return this._appInjector(requestor).get(key);
|
||||||
if (isPresent(requestor) && this._isComponentKey(requestor)) {
|
}
|
||||||
appInjector = this._shadowDomAppInjector;
|
}
|
||||||
} else {
|
|
||||||
appInjector = this._lightDomAppInjector;
|
_appInjector(requestor:Key) {
|
||||||
}
|
if (isPresent(requestor) && this._isComponentKey(requestor)) {
|
||||||
return appInjector.get(key);
|
return this._shadowDomAppInjector;
|
||||||
|
} else {
|
||||||
|
return this._lightDomAppInjector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,9 +387,10 @@ export class ElementInjector extends TreeNode {
|
|||||||
return depth === 0;
|
return depth === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getSpecialObjectByKeyId(keyId:int) {
|
_getPreBuiltObjectByKeyId(keyId:int) {
|
||||||
var staticKeys = StaticKeys.instance();
|
var staticKeys = StaticKeys.instance();
|
||||||
if (keyId === staticKeys.viewId) return this._view;
|
if (keyId === staticKeys.viewId) return this._preBuiltObjects.view;
|
||||||
|
if (keyId === staticKeys.ngElementId) return this._preBuiltObjects.element;
|
||||||
//TODO add other objects as needed
|
//TODO add other objects as needed
|
||||||
return _undefined;
|
return _undefined;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {View} from 'core/compiler/view';
|
import {View} from 'core/compiler/view';
|
||||||
|
import {NgElement} from 'core/dom/element';
|
||||||
import {Key} from 'di/di';
|
import {Key} from 'di/di';
|
||||||
import {isBlank} from 'facade/lang';
|
import {isBlank} from 'facade/lang';
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ export class StaticKeys {
|
|||||||
constructor() {
|
constructor() {
|
||||||
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
|
//TODO: vsavkin Key.annotate(Key.get(View), 'static')
|
||||||
this.viewId = Key.get(View).id;
|
this.viewId = Key.get(View).id;
|
||||||
|
this.ngElementId = Key.get(NgElement).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static instance() {
|
static instance() {
|
||||||
|
@ -4,13 +4,14 @@ import {ProtoWatchGroup, WatchGroup, WatchGroupDispatcher} from 'change_detectio
|
|||||||
import {Record} from 'change_detection/record';
|
import {Record} from 'change_detection/record';
|
||||||
import {AST} from 'change_detection/parser/ast';
|
import {AST} from 'change_detection/parser/ast';
|
||||||
|
|
||||||
import {ProtoElementInjector, ElementInjector} from './element_injector';
|
import {ProtoElementInjector, ElementInjector, PreBuiltObjects} from './element_injector';
|
||||||
import {ElementBinder} from './element_binder';
|
import {ElementBinder} from './element_binder';
|
||||||
import {AnnotatedType} from './annotated_type';
|
import {AnnotatedType} from './annotated_type';
|
||||||
import {SetterFn} from 'change_detection/parser/closure_map';
|
import {SetterFn} from 'change_detection/parser/closure_map';
|
||||||
import {FIELD, IMPLEMENTS, int, isPresent, isBlank} from 'facade/lang';
|
import {FIELD, IMPLEMENTS, int, isPresent, isBlank} from 'facade/lang';
|
||||||
import {List} from 'facade/collection';
|
import {List} from 'facade/collection';
|
||||||
import {Injector} from 'di/di';
|
import {Injector} from 'di/di';
|
||||||
|
import {NgElement} from 'core/dom/element';
|
||||||
|
|
||||||
const NG_BINDING_CLASS = 'ng-binding';
|
const NG_BINDING_CLASS = 'ng-binding';
|
||||||
|
|
||||||
@ -94,7 +95,6 @@ export class ProtoView {
|
|||||||
var rootElementInjectors = ProtoView._rootElementInjectors(elementInjectors);
|
var rootElementInjectors = ProtoView._rootElementInjectors(elementInjectors);
|
||||||
var textNodes = ProtoView._textNodes(elements, binders);
|
var textNodes = ProtoView._textNodes(elements, binders);
|
||||||
var bindElements = ProtoView._bindElements(elements, binders);
|
var bindElements = ProtoView._bindElements(elements, binders);
|
||||||
ProtoView._instantiateDirectives(elementInjectors, appInjector);
|
|
||||||
|
|
||||||
var viewNodes;
|
var viewNodes;
|
||||||
if (clone instanceof TemplateElement) {
|
if (clone instanceof TemplateElement) {
|
||||||
@ -102,8 +102,12 @@ export class ProtoView {
|
|||||||
} else {
|
} else {
|
||||||
viewNodes = [clone];
|
viewNodes = [clone];
|
||||||
}
|
}
|
||||||
return new View(viewNodes, elementInjectors, rootElementInjectors, textNodes,
|
var view = new View(viewNodes, elementInjectors, rootElementInjectors, textNodes,
|
||||||
bindElements, this.protoWatchGroup, context);
|
bindElements, this.protoWatchGroup, context);
|
||||||
|
|
||||||
|
ProtoView._instantiateDirectives(view, elements, elementInjectors, appInjector);
|
||||||
|
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
bindElement(protoElementInjector:ProtoElementInjector,
|
bindElement(protoElementInjector:ProtoElementInjector,
|
||||||
@ -173,15 +177,15 @@ export class ProtoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static _instantiateDirectives(
|
static _instantiateDirectives(
|
||||||
injectors:List<ElementInjectors>, appInjector:Injector) {
|
view: View, elements:List, injectors:List<ElementInjectors>, appInjector:Injector) {
|
||||||
for (var i = 0; i < injectors.length; ++i) {
|
for (var i = 0; i < injectors.length; ++i) {
|
||||||
if (injectors[i] != null) injectors[i].instantiateDirectives(appInjector, null);
|
var preBuiltObjs = new PreBuiltObjects(view, new NgElement(elements[i]));
|
||||||
|
if (injectors[i] != null) injectors[i].instantiateDirectives(appInjector, null, preBuiltObjs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static _createElementInjector(element, parent:ElementInjector, proto:ProtoElementInjector) {
|
static _createElementInjector(element, parent:ElementInjector, proto:ProtoElementInjector) {
|
||||||
//TODO: vsavkin: pass element to `proto.instantiate()` once https://github.com/angular/angular/pull/98 is merged
|
return proto.instantiate(parent, null);
|
||||||
return proto.instantiate(parent, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static _rootElementInjectors(injectors) {
|
static _rootElementInjectors(injectors) {
|
||||||
|
5
modules/core/src/dom/element.js
Normal file
5
modules/core/src/dom/element.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export class NgElement {
|
||||||
|
constructor(domElement) {
|
||||||
|
this.domElement = domElement;
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach} from 'test_lib/test_lib';
|
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach} from 'test_lib/test_lib';
|
||||||
import {isBlank, isPresent, FIELD, IMPLEMENTS} from 'facade/lang';
|
import {isBlank, isPresent, FIELD, IMPLEMENTS} from 'facade/lang';
|
||||||
import {ListWrapper, MapWrapper, List} from 'facade/collection';
|
import {ListWrapper, MapWrapper, List} from 'facade/collection';
|
||||||
import {ProtoElementInjector, VIEW_KEY} from 'core/compiler/element_injector';
|
import {ProtoElementInjector, PreBuiltObjects} from 'core/compiler/element_injector';
|
||||||
import {Parent, Ancestor} from 'core/annotations/visibility';
|
import {Parent, Ancestor} from 'core/annotations/visibility';
|
||||||
import {Injector, Inject, bind} from 'di/di';
|
import {Injector, Inject, bind} from 'di/di';
|
||||||
import {View} from 'core/compiler/view';
|
import {View} from 'core/compiler/view';
|
||||||
|
import {NgElement} from 'core/dom/element';
|
||||||
|
|
||||||
@IMPLEMENTS(View)
|
@IMPLEMENTS(View)
|
||||||
class DummyView {}
|
class DummyView {}
|
||||||
@ -60,6 +61,8 @@ class NeedsView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
|
var defaultPreBuiltObjects = new PreBuiltObjects(null, null);
|
||||||
|
|
||||||
function humanize(tree, names:List) {
|
function humanize(tree, names:List) {
|
||||||
var lookupName = (item) =>
|
var lookupName = (item) =>
|
||||||
ListWrapper.last(
|
ListWrapper.last(
|
||||||
@ -70,13 +73,14 @@ export function main() {
|
|||||||
return [lookupName(tree), children];
|
return [lookupName(tree), children];
|
||||||
}
|
}
|
||||||
|
|
||||||
function injector(bindings, lightDomAppInjector = null, shadowDomAppInjector = null, props = null) {
|
function injector(bindings, lightDomAppInjector = null, shadowDomAppInjector = null, preBuiltObjects = null) {
|
||||||
if (isBlank(lightDomAppInjector)) lightDomAppInjector = new Injector([]);
|
if (isBlank(lightDomAppInjector)) lightDomAppInjector = new Injector([]);
|
||||||
if (isBlank(props)) props = {"view": null};
|
|
||||||
|
|
||||||
var proto = new ProtoElementInjector(null, 0, bindings, isPresent(shadowDomAppInjector));
|
var proto = new ProtoElementInjector(null, 0, bindings, isPresent(shadowDomAppInjector));
|
||||||
var inj = proto.instantiate(null, null, props["view"]);
|
var inj = proto.instantiate(null, null);
|
||||||
inj.instantiateDirectives(lightDomAppInjector, shadowDomAppInjector);
|
var preBuilt = isPresent(preBuiltObjects) ? preBuiltObjects : defaultPreBuiltObjects;
|
||||||
|
|
||||||
|
inj.instantiateDirectives(lightDomAppInjector, shadowDomAppInjector, preBuilt);
|
||||||
return inj;
|
return inj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,12 +88,12 @@ export function main() {
|
|||||||
var inj = new Injector([]);
|
var inj = new Injector([]);
|
||||||
|
|
||||||
var protoParent = new ProtoElementInjector(null, 0, parentBindings);
|
var protoParent = new ProtoElementInjector(null, 0, parentBindings);
|
||||||
var parent = protoParent.instantiate(null, null, null);
|
var parent = protoParent.instantiate(null, null);
|
||||||
parent.instantiateDirectives(inj, null);
|
parent.instantiateDirectives(inj, null, defaultPreBuiltObjects);
|
||||||
|
|
||||||
var protoChild = new ProtoElementInjector(protoParent, 1, childBindings);
|
var protoChild = new ProtoElementInjector(protoParent, 1, childBindings);
|
||||||
var child = protoChild.instantiate(parent, null, null);
|
var child = protoChild.instantiate(parent, null);
|
||||||
child.instantiateDirectives(inj, null);
|
child.instantiateDirectives(inj, null, defaultPreBuiltObjects);
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
@ -99,12 +103,12 @@ export function main() {
|
|||||||
var shadowInj = inj.createChild([]);
|
var shadowInj = inj.createChild([]);
|
||||||
|
|
||||||
var protoParent = new ProtoElementInjector(null, 0, hostBindings, true);
|
var protoParent = new ProtoElementInjector(null, 0, hostBindings, true);
|
||||||
var host = protoParent.instantiate(null, null, null);
|
var host = protoParent.instantiate(null, null);
|
||||||
host.instantiateDirectives(inj, shadowInj);
|
host.instantiateDirectives(inj, shadowInj, null);
|
||||||
|
|
||||||
var protoChild = new ProtoElementInjector(protoParent, 0, shadowBindings, false);
|
var protoChild = new ProtoElementInjector(protoParent, 0, shadowBindings, false);
|
||||||
var shadow = protoChild.instantiate(null, host, null);
|
var shadow = protoChild.instantiate(null, host);
|
||||||
shadow.instantiateDirectives(shadowInj, null);
|
shadow.instantiateDirectives(shadowInj, null, null);
|
||||||
|
|
||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
@ -116,9 +120,9 @@ export function main() {
|
|||||||
var protoChild1 = new ProtoElementInjector(protoParent, 1, []);
|
var protoChild1 = new ProtoElementInjector(protoParent, 1, []);
|
||||||
var protoChild2 = new ProtoElementInjector(protoParent, 2, []);
|
var protoChild2 = new ProtoElementInjector(protoParent, 2, []);
|
||||||
|
|
||||||
var p = protoParent.instantiate(null, null, null);
|
var p = protoParent.instantiate(null, null);
|
||||||
var c1 = protoChild1.instantiate(p, null, null);
|
var c1 = protoChild1.instantiate(p, null);
|
||||||
var c2 = protoChild2.instantiate(p, null, null);
|
var c2 = protoChild2.instantiate(p, null);
|
||||||
|
|
||||||
expect(humanize(p, [
|
expect(humanize(p, [
|
||||||
[p, 'parent'],
|
[p, 'parent'],
|
||||||
@ -166,9 +170,9 @@ export function main() {
|
|||||||
expect(d.service).toEqual("service");
|
expect(d.service).toEqual("service");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should instantiate directives that depend on special objects", function () {
|
it("should instantiate directives that depend on pre built objects", function () {
|
||||||
var view = new DummyView();
|
var view = new DummyView();
|
||||||
var inj = injector([NeedsView], null, null, {'view':view});
|
var inj = injector([NeedsView], null, null, new PreBuiltObjects(view, null));
|
||||||
|
|
||||||
expect(inj.get(NeedsView).view).toBe(view);
|
expect(inj.get(NeedsView).view).toBe(view);
|
||||||
});
|
});
|
||||||
@ -258,15 +262,6 @@ export function main() {
|
|||||||
expect(() => inj.getAtIndex(10)).toThrowError(
|
expect(() => inj.getAtIndex(10)).toThrowError(
|
||||||
'Index 10 is out-of-bounds.');
|
'Index 10 is out-of-bounds.');
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe("special objects", function () {
|
|
||||||
it("should return view", function () {
|
|
||||||
var view = new DummyView();
|
|
||||||
var inj = injector([], null, null, {"view" : view});
|
|
||||||
|
|
||||||
expect(inj.get(View)).toEqual(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle cyclic dependencies", function () {
|
it("should handle cyclic dependencies", function () {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
@ -275,7 +270,23 @@ export function main() {
|
|||||||
bind(B_Needs_A).toFactory((a) => new B_Needs_A(a), [A_Needs_B])
|
bind(B_Needs_A).toFactory((a) => new B_Needs_A(a), [A_Needs_B])
|
||||||
]);
|
]);
|
||||||
}).toThrowError('Cannot instantiate cyclic dependency! ' +
|
}).toThrowError('Cannot instantiate cyclic dependency! ' +
|
||||||
'(A_Needs_B -> B_Needs_A -> A_Needs_B)');
|
'(A_Needs_B -> B_Needs_A -> A_Needs_B)');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("pre built objects", function () {
|
||||||
|
it("should return view", function () {
|
||||||
|
var view = new DummyView();
|
||||||
|
var inj = injector([], null, null, new PreBuiltObjects(view, null));
|
||||||
|
|
||||||
|
expect(inj.get(View)).toEqual(view);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return element", function () {
|
||||||
|
var element = new NgElement(null);
|
||||||
|
var inj = injector([], null, null, new PreBuiltObjects(null, element));
|
||||||
|
|
||||||
|
expect(inj.get(NgElement)).toEqual(element);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user