refactor(ElementInjector): use `index` instead of the `elementInjector` field to instantiate element injectors
This commit is contained in:
parent
7908533336
commit
b5f6417635
|
@ -8,9 +8,9 @@ export function run () {
|
||||||
var appInjector = new Injector([]);
|
var appInjector = new Injector([]);
|
||||||
|
|
||||||
var bindings = [A, B, C];
|
var bindings = [A, B, C];
|
||||||
var proto = new ProtoElementInjector(null, 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({view:null});
|
var ei = proto.instantiate({view:null, parentElementInjector: null});
|
||||||
ei.instantiateDirectives(appInjector);
|
ei.instantiateDirectives(appInjector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@ export function run () {
|
||||||
], false)];
|
], false)];
|
||||||
|
|
||||||
|
|
||||||
var proto = new ProtoElementInjector(null, 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({view:null});
|
var ei = proto.instantiate({view:null, parentElementInjector: null});
|
||||||
ei.instantiateDirectives(appInjector);
|
ei.instantiateDirectives(appInjector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ export function run () {
|
||||||
var appInjector = new Injector([]);
|
var appInjector = new Injector([]);
|
||||||
|
|
||||||
var bindings = [A, B, C];
|
var bindings = [A, B, C];
|
||||||
var proto = new ProtoElementInjector(null, bindings);
|
var proto = new ProtoElementInjector(null, 0, bindings);
|
||||||
var ei = proto.instantiate({view:null});
|
var ei = proto.instantiate({view:null, parentElementInjector: null});
|
||||||
|
|
||||||
for (var i = 0; i < ITERATIONS; ++i) {
|
for (var i = 0; i < ITERATIONS; ++i) {
|
||||||
ei.clearDirectives();
|
ei.clearDirectives();
|
||||||
|
|
|
@ -93,39 +93,7 @@ ElementInjector (ElementModule):
|
||||||
PERF BENCHMARK: http://www.williambrownstreet.net/blog/2014/04/faster-angularjs-rendering-angularjs-and-reactjs/
|
PERF BENCHMARK: http://www.williambrownstreet.net/blog/2014/04/faster-angularjs-rendering-angularjs-and-reactjs/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class ProtoElementInjector extends TreeNode {
|
export class ProtoElementInjector {
|
||||||
/**
|
|
||||||
parent:ProtoDirectiveInjector;
|
|
||||||
next:ProtoDirectiveInjector;
|
|
||||||
prev:ProtoDirectiveInjector;
|
|
||||||
head:ProtoDirectiveInjector;
|
|
||||||
tail:ProtoDirectiveInjector;
|
|
||||||
DirectiveInjector cloningInstance;
|
|
||||||
KeyMap keyMap;
|
|
||||||
/// Because DI tree is sparse, this shows how far away is the Parent DI
|
|
||||||
parentDistance:int = 1; /// 1 for non-sparse/normal depth.
|
|
||||||
|
|
||||||
cKey:int; cFactory:Function; cParams:List<int>;
|
|
||||||
_keyId0:int; factory0:Function; params0:List<int>;
|
|
||||||
_keyId1:int; factory1:Function; params1:List<int>;
|
|
||||||
_keyId2:int; factory2:Function; params2:List<int>;
|
|
||||||
_keyId3:int; factory3:Function; params3:List<int>;
|
|
||||||
_keyId4:int; factory4:Function; params4:List<int>;
|
|
||||||
_keyId5:int; factory5:Function; params5:List<int>;
|
|
||||||
_keyId6:int; factory6:Function; params6:List<int>;
|
|
||||||
_keyId7:int; factory7:Function; params7:List<int>;
|
|
||||||
_keyId8:int; factory8:Function; params8:List<int>;
|
|
||||||
_keyId9:int; factory9:Function; params9:List<int>;
|
|
||||||
|
|
||||||
query_keyId0:int;
|
|
||||||
query_keyId1:int;
|
|
||||||
|
|
||||||
textNodes:List<int>;
|
|
||||||
events:Map<string, Expression>;
|
|
||||||
|
|
||||||
elementInjector:ElementInjector;
|
|
||||||
*/
|
|
||||||
@FIELD('_elementInjector:ElementInjector')
|
|
||||||
@FIELD('_binding0:Binding')
|
@FIELD('_binding0:Binding')
|
||||||
@FIELD('_binding1:Binding')
|
@FIELD('_binding1:Binding')
|
||||||
@FIELD('_binding2:Binding')
|
@FIELD('_binding2:Binding')
|
||||||
|
@ -146,10 +114,11 @@ export class ProtoElementInjector extends TreeNode {
|
||||||
@FIELD('_key7:int')
|
@FIELD('_key7:int')
|
||||||
@FIELD('_key8:int')
|
@FIELD('_key8:int')
|
||||||
@FIELD('_key9:int')
|
@FIELD('_key9:int')
|
||||||
constructor(parent:ProtoElementInjector, bindings:List) {
|
@FIELD('final parent:ProtoElementInjector')
|
||||||
super(parent);
|
@FIELD('final index:int')
|
||||||
|
constructor(parent:ProtoElementInjector, index:int, bindings:List) {
|
||||||
this._elementInjector = null;
|
this.parent = parent;
|
||||||
|
this.index = index;
|
||||||
|
|
||||||
this._binding0 = null; this._keyId0 = null;
|
this._binding0 = null; this._keyId0 = null;
|
||||||
this._binding1 = null; this._keyId1 = null;
|
this._binding1 = null; this._keyId1 = null;
|
||||||
|
@ -179,15 +148,12 @@ export class ProtoElementInjector extends TreeNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiate({view}):ElementInjector {
|
instantiate({view, parentElementInjector}):ElementInjector {
|
||||||
var p = this._parent;
|
return new ElementInjector({
|
||||||
var parentElementInjector = p === null ? null : p._elementInjector;
|
|
||||||
this._elementInjector = new ElementInjector({
|
|
||||||
proto: this,
|
proto: this,
|
||||||
parent: parentElementInjector,
|
parent: parentElementInjector,
|
||||||
view: view
|
view: view
|
||||||
});
|
});
|
||||||
return this._elementInjector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createBinding(bindingOrType) {
|
_createBinding(bindingOrType) {
|
||||||
|
@ -198,10 +164,6 @@ export class ProtoElementInjector extends TreeNode {
|
||||||
return new Binding(b.key, b.factory, deps, b.providedAsPromise);
|
return new Binding(b.key, b.factory, deps, b.providedAsPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearElementInjector() {
|
|
||||||
this._elementInjector = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasBindings():boolean {
|
get hasBindings():boolean {
|
||||||
return isPresent(this._binding0);
|
return isPresent(this._binding0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,13 +99,9 @@ export class ProtoView {
|
||||||
static _createElementInjectors(elements, binders) {
|
static _createElementInjectors(elements, binders) {
|
||||||
var injectors = ListWrapper.createFixedSize(binders.length);
|
var injectors = ListWrapper.createFixedSize(binders.length);
|
||||||
for (var i = 0; i < binders.length; ++i) {
|
for (var i = 0; i < binders.length; ++i) {
|
||||||
injectors[i] = ProtoView._createElementInjector(
|
var proto = binders[i].protoElementInjector;
|
||||||
elements[i], binders[i].protoElementInjector);
|
var parentElementInjector = isPresent(proto.parent) ? injectors[proto.parent.index] : null;
|
||||||
}
|
injectors[i] = ProtoView._createElementInjector(elements[i], parentElementInjector, proto);
|
||||||
// Cannot be rolled into loop above, because parentInjector pointers need
|
|
||||||
// to be set on the children.
|
|
||||||
for (var i = 0; i < binders.length; ++i) {
|
|
||||||
binders[i].protoElementInjector.clearElementInjector();
|
|
||||||
}
|
}
|
||||||
return injectors;
|
return injectors;
|
||||||
}
|
}
|
||||||
|
@ -117,9 +113,9 @@ export class ProtoView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static _createElementInjector(element, proto) {
|
static _createElementInjector(element, parent:ElementInjector, proto:ProtoElementInjector) {
|
||||||
//TODO: vsavkin: pass element to `proto.instantiate()` once https://github.com/angular/angular/pull/98 is merged
|
//TODO: vsavkin: pass element to `proto.instantiate()` once https://github.com/angular/angular/pull/98 is merged
|
||||||
return proto.hasBindings ? proto.instantiate({view:null}) : null;
|
return proto.hasBindings ? proto.instantiate({view:null, parentElementInjector:parent}) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _rootElementInjectors(injectors) {
|
static _rootElementInjectors(injectors) {
|
||||||
|
|
|
@ -70,8 +70,8 @@ export function main() {
|
||||||
if (isBlank(appInjector)) appInjector = new Injector([]);
|
if (isBlank(appInjector)) appInjector = new Injector([]);
|
||||||
if (isBlank(props)) props = {};
|
if (isBlank(props)) props = {};
|
||||||
|
|
||||||
var proto = new ProtoElementInjector(null, bindings);
|
var proto = new ProtoElementInjector(null, 0, bindings);
|
||||||
var inj = proto.instantiate({view: props["view"]});
|
var inj = proto.instantiate({view: props["view"], parentElementInjector:null});
|
||||||
inj.instantiateDirectives(appInjector);
|
inj.instantiateDirectives(appInjector);
|
||||||
return inj;
|
return inj;
|
||||||
}
|
}
|
||||||
|
@ -79,41 +79,27 @@ export function main() {
|
||||||
function parentChildInjectors(parentBindings, childBindings) {
|
function parentChildInjectors(parentBindings, childBindings) {
|
||||||
var inj = new Injector([]);
|
var inj = new Injector([]);
|
||||||
|
|
||||||
var protoParent = new ProtoElementInjector(null, parentBindings);
|
var protoParent = new ProtoElementInjector(null, 0, parentBindings);
|
||||||
var parent = protoParent.instantiate({view: null});
|
var parent = protoParent.instantiate({view: null, parentElementInjector: null});
|
||||||
parent.instantiateDirectives(inj);
|
parent.instantiateDirectives(inj);
|
||||||
|
|
||||||
var protoChild = new ProtoElementInjector(protoParent, childBindings);
|
var protoChild = new ProtoElementInjector(protoParent, 1, childBindings);
|
||||||
var child = protoChild.instantiate({view: null});
|
var child = protoChild.instantiate({view: null, parentElementInjector: parent});
|
||||||
child.instantiateDirectives(inj);
|
child.instantiateDirectives(inj);
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("ElementInjector", function () {
|
describe("ElementInjector", function () {
|
||||||
describe("proto injectors", function () {
|
|
||||||
it("should construct a proto tree", function () {
|
|
||||||
var p = new ProtoElementInjector(null, []);
|
|
||||||
var c1 = new ProtoElementInjector(p, []);
|
|
||||||
var c2 = new ProtoElementInjector(p, []);
|
|
||||||
|
|
||||||
expect(humanize(p, [
|
|
||||||
[p, 'parent'],
|
|
||||||
[c1, 'child1'],
|
|
||||||
[c2, 'child2']
|
|
||||||
])).toEqual(["parent", ["child1", "child2"]]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("instantiate", function () {
|
describe("instantiate", function () {
|
||||||
it("should create an element injector", function () {
|
it("should create an element injector", function () {
|
||||||
var protoParent = new ProtoElementInjector(null, []);
|
var protoParent = new ProtoElementInjector(null, 0, []);
|
||||||
var protoChild1 = new ProtoElementInjector(protoParent, []);
|
var protoChild1 = new ProtoElementInjector(protoParent, 1, []);
|
||||||
var protoChild2 = new ProtoElementInjector(protoParent, []);
|
var protoChild2 = new ProtoElementInjector(protoParent, 2, []);
|
||||||
|
|
||||||
var p = protoParent.instantiate({view: null});
|
var p = protoParent.instantiate({view: null, parentElementInjector: null});
|
||||||
var c1 = protoChild1.instantiate({view: null});
|
var c1 = protoChild1.instantiate({view: null, parentElementInjector: p});
|
||||||
var c2 = protoChild2.instantiate({view: null});
|
var c2 = protoChild2.instantiate({view: null, parentElementInjector: p});
|
||||||
|
|
||||||
expect(humanize(p, [
|
expect(humanize(p, [
|
||||||
[p, 'parent'],
|
[p, 'parent'],
|
||||||
|
@ -125,12 +111,12 @@ export function main() {
|
||||||
|
|
||||||
describe("hasBindings", function () {
|
describe("hasBindings", function () {
|
||||||
it("should be true when there are bindings", function () {
|
it("should be true when there are bindings", function () {
|
||||||
var p = new ProtoElementInjector(null, [Directive]);
|
var p = new ProtoElementInjector(null, 0, [Directive]);
|
||||||
expect(p.hasBindings).toBeTruthy();
|
expect(p.hasBindings).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be false otherwise", function () {
|
it("should be false otherwise", function () {
|
||||||
var p = new ProtoElementInjector(null, []);
|
var p = new ProtoElementInjector(null, 0, []);
|
||||||
expect(p.hasBindings).toBeFalsy();
|
expect(p.hasBindings).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,14 +34,14 @@ export function main() {
|
||||||
'</section>';
|
'</section>';
|
||||||
|
|
||||||
function templateElementBinders() {
|
function templateElementBinders() {
|
||||||
var sectionPI = new ElementBinder(new ProtoElementInjector(null, []),
|
var sectionPI = new ElementBinder(new ProtoElementInjector(null, 0, []),
|
||||||
[0], false);
|
[0], false);
|
||||||
|
|
||||||
var divPI = new ElementBinder(new ProtoElementInjector(
|
var divPI = new ElementBinder(new ProtoElementInjector(
|
||||||
sectionPI.protoElementInjector, [Directive]), [], false);
|
sectionPI.protoElementInjector, 1, [Directive]), [], false);
|
||||||
|
|
||||||
var spanPI = new ElementBinder(new ProtoElementInjector(
|
var spanPI = new ElementBinder(new ProtoElementInjector(
|
||||||
divPI.protoElementInjector, []), [], true);
|
divPI.protoElementInjector, 2, []), [], true);
|
||||||
return [sectionPI, divPI, spanPI];
|
return [sectionPI, divPI, spanPI];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@ export function main() {
|
||||||
'</section>');
|
'</section>');
|
||||||
|
|
||||||
var sectionPI = new ElementBinder(new ProtoElementInjector(
|
var sectionPI = new ElementBinder(new ProtoElementInjector(
|
||||||
null, [Directive]), [], false);
|
null, 0, [Directive]), [], false);
|
||||||
var divPI = new ElementBinder(new ProtoElementInjector(
|
var divPI = new ElementBinder(new ProtoElementInjector(
|
||||||
sectionPI.protoElementInjector, [Directive]), [], false);
|
sectionPI.protoElementInjector, 1, [Directive]), [], false);
|
||||||
|
|
||||||
var pv = new ProtoView(template, [sectionPI, divPI],
|
var pv = new ProtoView(template, [sectionPI, divPI],
|
||||||
new ProtoWatchGroup(), false);
|
new ProtoWatchGroup(), false);
|
||||||
|
|
Loading…
Reference in New Issue