Skip to content

Commit 457cbaa

Browse files
committed
fix(ProtoView): element injector should have either a parent or a host
fix angular#359
1 parent 09092b2 commit 457cbaa

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

modules/core/src/compiler/pipeline/proto_element_injector_builder.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,10 @@ export class ProtoElementInjectorBuilder extends CompileStep {
4949
}
5050

5151
_getParentProtoElementInjector(parent, current) {
52-
var parentProtoElementInjector = null;
53-
if (current.isViewRoot) {
54-
parentProtoElementInjector = null;
55-
} else if (isPresent(parent)) {
56-
parentProtoElementInjector = parent.inheritedProtoElementInjector;
52+
if (isPresent(parent) && !current.isViewRoot) {
53+
return parent.inheritedProtoElementInjector;
5754
}
58-
return parentProtoElementInjector;
55+
return null;
5956
}
6057

6158
_collectDirectiveBindings(pipelineElement) {

modules/core/src/compiler/view.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,11 @@ export class ProtoView {
309309
// elementInjectors and rootElementInjectors
310310
var protoElementInjector = binder.protoElementInjector;
311311
if (isPresent(protoElementInjector)) {
312-
var parentElementInjector = isPresent(protoElementInjector.parent) ? elementInjectors[protoElementInjector.parent.index] : null;
313-
elementInjector = protoElementInjector.instantiate(parentElementInjector, hostElementInjector);
314-
if (isBlank(parentElementInjector)) {
312+
if (isPresent(protoElementInjector.parent)) {
313+
var parentElementInjector = elementInjectors[protoElementInjector.parent.index];
314+
elementInjector = protoElementInjector.instantiate(parentElementInjector, null);
315+
} else {
316+
elementInjector = protoElementInjector.instantiate(null, hostElementInjector);
315317
ListWrapper.push(rootElementInjectors, elementInjector);
316318
}
317319
}

modules/core/test/compiler/view_spec.js

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import {Component, Decorator, Template} from 'core/annotations/annotations';
77
import {OnChange} from 'core/core';
88
import {Lexer, Parser, ProtoRecordRange, ChangeDetector} from 'change_detection/change_detection';
99
import {TemplateConfig} from 'core/annotations/template_config';
10+
import {List} from 'facade/collection';
1011
import {DOM, Element} from 'facade/dom';
11-
import {FIELD} from 'facade/lang';
12+
import {int} from 'facade/lang';
1213
import {Injector} from 'di/di';
1314
import {View} from 'core/compiler/view';
1415
import {ViewPort} from 'core/compiler/viewport';
@@ -206,6 +207,36 @@ export function main() {
206207
expect(view.elementInjectors[0].get(SomeDirective) instanceof SomeDirective).toBe(true);
207208
expect(view.elementInjectors[1].parent).toBe(view.elementInjectors[0]);
208209
});
210+
211+
it('should not pass the host injector when a parent injector exists', () => {
212+
var pv = new ProtoView(createElement('<div class="ng-binding"><span class="ng-binding"></span></div>'),
213+
new ProtoRecordRange());
214+
var protoParent = new ProtoElementInjector(null, 0, [SomeDirective]);
215+
pv.bindElement(protoParent);
216+
var testProtoElementInjector = new TestProtoElementInjector(protoParent, 1, [AnotherDirective]);
217+
pv.bindElement(testProtoElementInjector);
218+
219+
var hostProtoInjector = new ProtoElementInjector(null, 0, []);
220+
var hostInjector = hostProtoInjector.instantiate(null, null);
221+
var view;
222+
expect(() => view = pv.instantiate(hostInjector)).not.toThrow();
223+
expect(testProtoElementInjector.parentElementInjector).toBe(view.elementInjectors[0]);
224+
expect(testProtoElementInjector.hostElementInjector).toBeNull();
225+
});
226+
227+
it('should pass the host injector when there is no parent injector', () => {
228+
var pv = new ProtoView(createElement('<div class="ng-binding"><span class="ng-binding"></span></div>'),
229+
new ProtoRecordRange());
230+
pv.bindElement(new ProtoElementInjector(null, 0, [SomeDirective]));
231+
var testProtoElementInjector = new TestProtoElementInjector(null, 1, [AnotherDirective]);
232+
pv.bindElement(testProtoElementInjector);
233+
234+
var hostProtoInjector = new ProtoElementInjector(null, 0, []);
235+
var hostInjector = hostProtoInjector.instantiate(null, null);
236+
expect(() => pv.instantiate(hostInjector)).not.toThrow();
237+
expect(testProtoElementInjector.parentElementInjector).toBeNull();
238+
expect(testProtoElementInjector.hostElementInjector).toBe(hostInjector);
239+
});
209240
});
210241

211242
describe('collect root element injectors', () => {
@@ -544,3 +575,18 @@ class MyEvaluationContext {
544575
function createElement(html) {
545576
return DOM.createTemplate(html).content.firstChild;
546577
}
578+
579+
class TestProtoElementInjector extends ProtoElementInjector {
580+
parentElementInjector: ElementInjector;
581+
hostElementInjector: ElementInjector;
582+
583+
constructor(parent:ProtoElementInjector, index:int, bindings:List, firstBindingIsComponent:boolean = false) {
584+
super(parent, index, bindings, firstBindingIsComponent);
585+
}
586+
587+
instantiate(parent:ElementInjector, host:ElementInjector):ElementInjector {
588+
this.parentElementInjector = parent;
589+
this.hostElementInjector = host;
590+
return super.instantiate(parent, host);
591+
}
592+
}

0 commit comments

Comments
 (0)