diff --git a/modules/angular2/src/core/compiler/element_injector.ts b/modules/angular2/src/core/compiler/element_injector.ts index b3e6003440..9955420eb7 100644 --- a/modules/angular2/src/core/compiler/element_injector.ts +++ b/modules/angular2/src/core/compiler/element_injector.ts @@ -189,10 +189,28 @@ export class TreeNode> { } } -export class DirectiveDependency extends Dependency { +export class DependencyWithVisibility extends Dependency { constructor(key: Key, asPromise: boolean, lazy: boolean, optional: boolean, properties: List, - public visibility: Visibility, public attributeName: string, public queryDirective) { + public visibility: Visibility) { super(key, asPromise, lazy, optional, properties); + } + + static createFrom(d: Dependency): Dependency { + return new DependencyWithVisibility(d.key, d.asPromise, d.lazy, d.optional, d.properties, + DependencyWithVisibility._visibility(d.properties)); + } + + static _visibility(properties): Visibility { + if (properties.length == 0) return self; + var p = ListWrapper.find(properties, p => p instanceof Visibility); + return isPresent(p) ? p : self; + } +} + +export class DirectiveDependency extends DependencyWithVisibility { + constructor(key: Key, asPromise: boolean, lazy: boolean, optional: boolean, properties: List, + visibility: Visibility, public attributeName: string, public queryDirective) { + super(key, asPromise, lazy, optional, properties, visibility); this._verify(); } @@ -207,17 +225,11 @@ export class DirectiveDependency extends Dependency { static createFrom(d: Dependency): Dependency { return new DirectiveDependency(d.key, d.asPromise, d.lazy, d.optional, d.properties, - DirectiveDependency._visibility(d.properties), + DependencyWithVisibility._visibility(d.properties), DirectiveDependency._attributeName(d.properties), DirectiveDependency._query(d.properties)); } - static _visibility(properties): Visibility { - if (properties.length == 0) return self; - var p = ListWrapper.find(properties, p => p instanceof Visibility); - return isPresent(p) ? p : self; - } - static _attributeName(properties): string { var p = ListWrapper.find(properties, (p) => p instanceof Attribute); return isPresent(p) ? p.attributeName : null; @@ -476,16 +488,24 @@ export class ProtoElementInjector { private static _createHostInjectorBindingData(bindings: List, bd: List) { ListWrapper.forEach(bindings, b => { - ListWrapper.forEach(b.resolvedHostInjectables, - b => { ListWrapper.push(bd, new BindingData(b, LIGHT_DOM)); }); + ListWrapper.forEach(b.resolvedHostInjectables, b => { + ListWrapper.push(bd, new BindingData(ProtoElementInjector._createBinding(b), LIGHT_DOM)); + }); }); } private static _createViewInjectorBindingData(bindings: List, bd: List) { var db = bindings[0]; - ListWrapper.forEach(db.resolvedViewInjectables, - b => ListWrapper.push(bd, new BindingData(b, SHADOW_DOM))); + ListWrapper.forEach( + db.resolvedViewInjectables, + b => ListWrapper.push(bd, + new BindingData(ProtoElementInjector._createBinding(b), SHADOW_DOM))); + } + + private static _createBinding(b: ResolvedBinding) { + var deps = ListWrapper.map(b.dependencies, d => DependencyWithVisibility.createFrom(d)); + return new ResolvedBinding(b.key, b.factory, deps, b.providedAsPromise); } constructor(parent: ProtoElementInjector, index: int, bd: List, @@ -909,9 +929,9 @@ export class ElementInjector extends TreeNode { return obj; } - private _getByDependency(dep: Dependency, requestor: Key) { + private _getByDependency(dep: DependencyWithVisibility, requestor: Key) { if (!(dep instanceof DirectiveDependency)) { - return this._getByKey(dep.key, self, dep.optional, requestor); + return this._getByKey(dep.key, dep.visibility, dep.optional, requestor); } var dirDep = dep; diff --git a/modules/angular2/src/di/binding.ts b/modules/angular2/src/di/binding.ts index a3cbecce82..c9d6c7ff92 100644 --- a/modules/angular2/src/di/binding.ts +++ b/modules/angular2/src/di/binding.ts @@ -492,5 +492,5 @@ function _extractToken(typeOrFunc, annotations) { } function _createDependency(token, asPromise, lazy, optional, depProps): Dependency { - return new Dependency(Key.get(token), asPromise, lazy, optional, depProps); + return new Dependency(Key.get(resolveForwardRef(token)), asPromise, lazy, optional, depProps); } diff --git a/modules/angular2/test/core/compiler/element_injector_spec.js b/modules/angular2/test/core/compiler/element_injector_spec.js index f1d7c0189a..9e990eb5c3 100644 --- a/modules/angular2/test/core/compiler/element_injector_spec.js +++ b/modules/angular2/test/core/compiler/element_injector_spec.js @@ -6,7 +6,7 @@ import {ProtoElementInjector, ElementInjector, PreBuiltObjects, DirectiveBinding import {Parent, Ancestor, Unbounded} from 'angular2/src/core/annotations_impl/visibility'; import {Attribute, Query} from 'angular2/src/core/annotations_impl/di'; import {Component, Directive, onDestroy} from 'angular2/src/core/annotations_impl/annotations'; -import {bind, Injector, Binding} from 'angular2/di'; +import {bind, Injector, Binding, resolveBindings} from 'angular2/di'; import {Optional, Inject} from 'angular2/src/di/annotations_impl'; import {AppProtoView, AppView} from 'angular2/src/core/compiler/view'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; @@ -528,6 +528,22 @@ export function main() { expect(inj.get('injectable2')).toEqual('injectable1-injectable2'); }); + it("should instantiate hostInjector injectables that have dependencies with set visibility", function () { + var childInj= parentChildInjectors([ + DirectiveBinding.createFromType(SimpleDirective, + new DummyDirective({hostInjector: [ + bind('injectable1').toValue('injectable1') + ]})) + ], [ + DirectiveBinding.createFromType(SimpleDirective, + new DummyDirective({hostInjector: [ + bind('injectable1').toValue('new-injectable1'), + bind('injectable2').toFactory((val) => `${val}-injectable2`, [[new Inject('injectable1'), new Parent()]]) + ]})) + ]); + expect(childInj.get('injectable2')).toEqual('injectable1-injectable2'); + }); + it("should instantiate components that depends on viewInjector dependencies", function () { var inj = injector([ DirectiveBinding.createFromType(NeedsService,