fix(di): changed host and view injector to respect visibility

This commit is contained in:
vsavkin 2015-05-21 08:35:32 -07:00
parent f210c41c1f
commit 705ee46f31
3 changed files with 53 additions and 17 deletions

View File

@ -189,10 +189,28 @@ export class TreeNode<T extends TreeNode<any>> {
}
}
export class DirectiveDependency extends Dependency {
export class DependencyWithVisibility extends Dependency {
constructor(key: Key, asPromise: boolean, lazy: boolean, optional: boolean, properties: List<any>,
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<any>,
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<ResolvedBinding>,
bd: List<BindingData>) {
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<ResolvedBinding>,
bd: List<BindingData>) {
var db = <DirectiveBinding>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<BindingData>,
@ -909,9 +929,9 @@ export class ElementInjector extends TreeNode<ElementInjector> {
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 = <DirectiveDependency>dep;

View File

@ -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);
}

View File

@ -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,