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>, 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); 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(); this._verify();
} }
@ -207,17 +225,11 @@ export class DirectiveDependency extends Dependency {
static createFrom(d: Dependency): Dependency { static createFrom(d: Dependency): Dependency {
return new DirectiveDependency(d.key, d.asPromise, d.lazy, d.optional, d.properties, 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._attributeName(d.properties),
DirectiveDependency._query(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 { static _attributeName(properties): string {
var p = ListWrapper.find(properties, (p) => p instanceof Attribute); var p = ListWrapper.find(properties, (p) => p instanceof Attribute);
return isPresent(p) ? p.attributeName : null; return isPresent(p) ? p.attributeName : null;
@ -476,16 +488,24 @@ export class ProtoElementInjector {
private static _createHostInjectorBindingData(bindings: List<ResolvedBinding>, private static _createHostInjectorBindingData(bindings: List<ResolvedBinding>,
bd: List<BindingData>) { bd: List<BindingData>) {
ListWrapper.forEach(bindings, b => { ListWrapper.forEach(bindings, b => {
ListWrapper.forEach(b.resolvedHostInjectables, ListWrapper.forEach(b.resolvedHostInjectables, b => {
b => { ListWrapper.push(bd, new BindingData(b, LIGHT_DOM)); }); ListWrapper.push(bd, new BindingData(ProtoElementInjector._createBinding(b), LIGHT_DOM));
});
}); });
} }
private static _createViewInjectorBindingData(bindings: List<ResolvedBinding>, private static _createViewInjectorBindingData(bindings: List<ResolvedBinding>,
bd: List<BindingData>) { bd: List<BindingData>) {
var db = <DirectiveBinding>bindings[0]; var db = <DirectiveBinding>bindings[0];
ListWrapper.forEach(db.resolvedViewInjectables, ListWrapper.forEach(
b => ListWrapper.push(bd, new BindingData(b, SHADOW_DOM))); 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>, constructor(parent: ProtoElementInjector, index: int, bd: List<BindingData>,
@ -909,9 +929,9 @@ export class ElementInjector extends TreeNode<ElementInjector> {
return obj; return obj;
} }
private _getByDependency(dep: Dependency, requestor: Key) { private _getByDependency(dep: DependencyWithVisibility, requestor: Key) {
if (!(dep instanceof DirectiveDependency)) { 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; var dirDep = <DirectiveDependency>dep;

View File

@ -492,5 +492,5 @@ function _extractToken(typeOrFunc, annotations) {
} }
function _createDependency(token, asPromise, lazy, optional, depProps): Dependency { 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 {Parent, Ancestor, Unbounded} from 'angular2/src/core/annotations_impl/visibility';
import {Attribute, Query} from 'angular2/src/core/annotations_impl/di'; import {Attribute, Query} from 'angular2/src/core/annotations_impl/di';
import {Component, Directive, onDestroy} from 'angular2/src/core/annotations_impl/annotations'; 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 {Optional, Inject} from 'angular2/src/di/annotations_impl';
import {AppProtoView, AppView} from 'angular2/src/core/compiler/view'; import {AppProtoView, AppView} from 'angular2/src/core/compiler/view';
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
@ -528,6 +528,22 @@ export function main() {
expect(inj.get('injectable2')).toEqual('injectable1-injectable2'); 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 () { it("should instantiate components that depends on viewInjector dependencies", function () {
var inj = injector([ var inj = injector([
DirectiveBinding.createFromType(NeedsService, DirectiveBinding.createFromType(NeedsService,