fix(ProtoView): element injector should have either a parent or a host
fix #359
This commit is contained in:
parent
09092b269c
commit
457cbaa39b
|
@ -49,13 +49,10 @@ export class ProtoElementInjectorBuilder extends CompileStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getParentProtoElementInjector(parent, current) {
|
_getParentProtoElementInjector(parent, current) {
|
||||||
var parentProtoElementInjector = null;
|
if (isPresent(parent) && !current.isViewRoot) {
|
||||||
if (current.isViewRoot) {
|
return parent.inheritedProtoElementInjector;
|
||||||
parentProtoElementInjector = null;
|
|
||||||
} else if (isPresent(parent)) {
|
|
||||||
parentProtoElementInjector = parent.inheritedProtoElementInjector;
|
|
||||||
}
|
}
|
||||||
return parentProtoElementInjector;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_collectDirectiveBindings(pipelineElement) {
|
_collectDirectiveBindings(pipelineElement) {
|
||||||
|
|
|
@ -309,9 +309,11 @@ export class ProtoView {
|
||||||
// elementInjectors and rootElementInjectors
|
// elementInjectors and rootElementInjectors
|
||||||
var protoElementInjector = binder.protoElementInjector;
|
var protoElementInjector = binder.protoElementInjector;
|
||||||
if (isPresent(protoElementInjector)) {
|
if (isPresent(protoElementInjector)) {
|
||||||
var parentElementInjector = isPresent(protoElementInjector.parent) ? elementInjectors[protoElementInjector.parent.index] : null;
|
if (isPresent(protoElementInjector.parent)) {
|
||||||
elementInjector = protoElementInjector.instantiate(parentElementInjector, hostElementInjector);
|
var parentElementInjector = elementInjectors[protoElementInjector.parent.index];
|
||||||
if (isBlank(parentElementInjector)) {
|
elementInjector = protoElementInjector.instantiate(parentElementInjector, null);
|
||||||
|
} else {
|
||||||
|
elementInjector = protoElementInjector.instantiate(null, hostElementInjector);
|
||||||
ListWrapper.push(rootElementInjectors, elementInjector);
|
ListWrapper.push(rootElementInjectors, elementInjector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@ import {Component, Decorator, Template} from 'core/annotations/annotations';
|
||||||
import {OnChange} from 'core/core';
|
import {OnChange} from 'core/core';
|
||||||
import {Lexer, Parser, ProtoRecordRange, ChangeDetector} from 'change_detection/change_detection';
|
import {Lexer, Parser, ProtoRecordRange, ChangeDetector} from 'change_detection/change_detection';
|
||||||
import {TemplateConfig} from 'core/annotations/template_config';
|
import {TemplateConfig} from 'core/annotations/template_config';
|
||||||
|
import {List} from 'facade/collection';
|
||||||
import {DOM, Element} from 'facade/dom';
|
import {DOM, Element} from 'facade/dom';
|
||||||
import {FIELD} from 'facade/lang';
|
import {int} from 'facade/lang';
|
||||||
import {Injector} from 'di/di';
|
import {Injector} from 'di/di';
|
||||||
import {View} from 'core/compiler/view';
|
import {View} from 'core/compiler/view';
|
||||||
import {ViewPort} from 'core/compiler/viewport';
|
import {ViewPort} from 'core/compiler/viewport';
|
||||||
|
@ -206,6 +207,36 @@ export function main() {
|
||||||
expect(view.elementInjectors[0].get(SomeDirective) instanceof SomeDirective).toBe(true);
|
expect(view.elementInjectors[0].get(SomeDirective) instanceof SomeDirective).toBe(true);
|
||||||
expect(view.elementInjectors[1].parent).toBe(view.elementInjectors[0]);
|
expect(view.elementInjectors[1].parent).toBe(view.elementInjectors[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not pass the host injector when a parent injector exists', () => {
|
||||||
|
var pv = new ProtoView(createElement('<div class="ng-binding"><span class="ng-binding"></span></div>'),
|
||||||
|
new ProtoRecordRange());
|
||||||
|
var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
|
||||||
|
pv.bindElement(protoParent);
|
||||||
|
var testProtoElementInjector = new TestProtoElementInjector(protoParent, 1, [AnotherDirective]);
|
||||||
|
pv.bindElement(testProtoElementInjector);
|
||||||
|
|
||||||
|
var hostProtoInjector = new ProtoElementInjector(null, 0, []);
|
||||||
|
var hostInjector = hostProtoInjector.instantiate(null, null);
|
||||||
|
var view;
|
||||||
|
expect(() => view = pv.instantiate(hostInjector)).not.toThrow();
|
||||||
|
expect(testProtoElementInjector.parentElementInjector).toBe(view.elementInjectors[0]);
|
||||||
|
expect(testProtoElementInjector.hostElementInjector).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass the host injector when there is no parent injector', () => {
|
||||||
|
var pv = new ProtoView(createElement('<div class="ng-binding"><span class="ng-binding"></span></div>'),
|
||||||
|
new ProtoRecordRange());
|
||||||
|
pv.bindElement(new ProtoElementInjector(null, 0, [SomeDirective]));
|
||||||
|
var testProtoElementInjector = new TestProtoElementInjector(null, 1, [AnotherDirective]);
|
||||||
|
pv.bindElement(testProtoElementInjector);
|
||||||
|
|
||||||
|
var hostProtoInjector = new ProtoElementInjector(null, 0, []);
|
||||||
|
var hostInjector = hostProtoInjector.instantiate(null, null);
|
||||||
|
expect(() => pv.instantiate(hostInjector)).not.toThrow();
|
||||||
|
expect(testProtoElementInjector.parentElementInjector).toBeNull();
|
||||||
|
expect(testProtoElementInjector.hostElementInjector).toBe(hostInjector);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('collect root element injectors', () => {
|
describe('collect root element injectors', () => {
|
||||||
|
@ -544,3 +575,18 @@ class MyEvaluationContext {
|
||||||
function createElement(html) {
|
function createElement(html) {
|
||||||
return DOM.createTemplate(html).content.firstChild;
|
return DOM.createTemplate(html).content.firstChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestProtoElementInjector extends ProtoElementInjector {
|
||||||
|
parentElementInjector: ElementInjector;
|
||||||
|
hostElementInjector: ElementInjector;
|
||||||
|
|
||||||
|
constructor(parent:ProtoElementInjector, index:int, bindings:List, firstBindingIsComponent:boolean = false) {
|
||||||
|
super(parent, index, bindings, firstBindingIsComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
instantiate(parent:ElementInjector, host:ElementInjector):ElementInjector {
|
||||||
|
this.parentElementInjector = parent;
|
||||||
|
this.hostElementInjector = host;
|
||||||
|
return super.instantiate(parent, host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue