cleanup(DI): clean up visibility decorators
BREAKING CHANGE: Replace @Ancestor() with @Host() @SkipSelf() Replace @Unbounded() wwith @SkipSelf() Replace @Ancestor({self:true}) with @Host() Replace @Unbounded({self:true}) with nothing Replace new AncestorMetadata() with [new HostMetadata(), new SkipSelfMetadata()] Replace new UnboundedMetadata() with new SkipSelfMetadata() Replace new Ancestor({self:true}) with new HostMetadata()
This commit is contained in:
parent
a9ec6b9064
commit
985627bd65
|
@ -5,7 +5,7 @@
|
|||
* Annotations provide the additional information that Angular requires in order to run your
|
||||
* application. This module
|
||||
* contains {@link Component}, {@link Directive}, and {@link View} annotations, as well as
|
||||
* the {@link Ancestor} annotation that is used by Angular to resolve dependencies.
|
||||
* the {@link Host} annotation that is used by Angular to resolve dependencies.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -8,12 +8,10 @@ export {
|
|||
InjectMetadata,
|
||||
OptionalMetadata,
|
||||
InjectableMetadata,
|
||||
VisibilityMetadata,
|
||||
SelfMetadata,
|
||||
AncestorMetadata,
|
||||
UnboundedMetadata,
|
||||
DependencyMetadata,
|
||||
DEFAULT_VISIBILITY
|
||||
HostMetadata,
|
||||
SkipSelfMetadata,
|
||||
DependencyMetadata
|
||||
} from './src/di/metadata';
|
||||
|
||||
// we have to reexport * because Dart and TS export two different sets of types
|
||||
|
|
|
@ -261,7 +261,7 @@ Injecting other directives into directives follows a similar mechanism as inject
|
|||
There are five kinds of visibilities:
|
||||
|
||||
* (no annotation): Inject dependent directives only if they are on the current element.
|
||||
* `@ancestor`: Inject a directive if it is at any element above the current element.
|
||||
* `@SkipSelf()`: Inject a directive if it is at any element above the current element.
|
||||
* `@child`: Inject a list of direct children which match a given type. (Used with `Query`)
|
||||
* `@descendant`: Inject a list of any children which match a given type. (Used with `Query`)
|
||||
|
||||
|
@ -299,8 +299,8 @@ class FieldSet { |
|
|||
@Directive({ selector: 'field' }) |
|
||||
class Field { |
|
||||
constructor( |
|
||||
@ancestor field:Form, |
|
||||
@ancestor field:FieldSet, |
|
||||
@SkipSelf() field:Form, |
|
||||
@SkipSelf() field:FieldSet, |
|
||||
) { ... } |
|
||||
} |
|
||||
|
|
||||
|
@ -336,7 +336,7 @@ Shadow DOM provides an encapsulation for components, so as a general rule it doe
|
|||
})
|
||||
class Kid {
|
||||
constructor(
|
||||
@Ancestor() dad:Dad,
|
||||
@SkipSelf() dad:Dad,
|
||||
@Optional() grandpa:Grandpa
|
||||
) {
|
||||
this.name = 'Billy';
|
||||
|
@ -353,7 +353,7 @@ class Kid {
|
|||
directives: [Kid]
|
||||
})
|
||||
class Dad {
|
||||
constructor(@Ancestor() dad:Grandpa) {
|
||||
constructor(@SkipSelf() dad:Grandpa) {
|
||||
this.name = 'Joe Jr';
|
||||
this.dad = dad.name;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {ListWrapper, isListLikeIterable, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {isBlank, isPresent, BaseException, CONST} from 'angular2/src/facade/lang';
|
||||
import {Pipe, PipeFactory} from './pipe';
|
||||
import {Injectable, UnboundedMetadata, OptionalMetadata} from 'angular2/di';
|
||||
import {Injectable, OptionalMetadata, SkipSelfMetadata} from 'angular2/di';
|
||||
import {ChangeDetectorRef} from '../change_detector_ref';
|
||||
import {Binding} from 'angular2/di';
|
||||
|
||||
|
@ -80,7 +80,7 @@ export class Pipes {
|
|||
return Pipes.create(config, pipes);
|
||||
},
|
||||
// Dependency technically isn't optional, but we can provide a better error message this way.
|
||||
deps: [[Pipes, new UnboundedMetadata(), new OptionalMetadata()]]
|
||||
deps: [[Pipes, new SkipSelfMetadata(), new OptionalMetadata()]]
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -53,11 +53,9 @@ import {DEFAULT} from 'angular2/change_detection';
|
|||
*
|
||||
* To inject other directives, declare the constructor parameter as:
|
||||
* - `directive:DirectiveType`: a directive on the current element only
|
||||
* - `@Ancestor() directive:DirectiveType`: any directive that matches the type between the current
|
||||
* - `@Host() directive:DirectiveType`: any directive that matches the type between the current
|
||||
* element and the
|
||||
* Shadow DOM root. Current element is not included in the resolution, therefore even if it could
|
||||
* resolve it, it will
|
||||
* be ignored.
|
||||
* Shadow DOM root.
|
||||
* - `@Query(DirectiveType) query:QueryList<DirectiveType>`: A live collection of direct child
|
||||
* directives.
|
||||
* - `@QueryDescendants(DirectiveType) query:QueryList<DirectiveType>`: A live collection of any
|
||||
|
@ -164,21 +162,19 @@ import {DEFAULT} from 'angular2/change_detection';
|
|||
* ### Injecting a directive from any ancestor elements
|
||||
*
|
||||
* Directives can inject other directives declared on any ancestor element (in the current Shadow
|
||||
* DOM), i.e. on the
|
||||
* parent element and its parents. By definition, a directive with an `@Ancestor` annotation does
|
||||
* not attempt to
|
||||
* resolve dependencies for the current element, even if this would satisfy the dependency.
|
||||
*
|
||||
* DOM), i.e. on the current element, the
|
||||
* parent element, or its parents.
|
||||
* ```
|
||||
* @Directive({ selector: '[my-directive]' })
|
||||
* class MyDirective {
|
||||
* constructor(@Ancestor() dependency: Dependency) {
|
||||
* constructor(@Host() dependency: Dependency) {
|
||||
* expect(dependency.id).toEqual(2);
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* `@Ancestor` checks the parent, as well as its parents recursively. If `dependency="2"` didn't
|
||||
* `@Host` checks the current element, the parent, as well as its parents recursively. If
|
||||
* `dependency="2"` didn't
|
||||
* exist on the direct parent, this injection would
|
||||
* have returned
|
||||
* `dependency="1"`.
|
||||
|
|
|
@ -25,7 +25,6 @@ import {
|
|||
AbstractBindingError,
|
||||
CyclicDependencyError,
|
||||
resolveForwardRef,
|
||||
VisibilityMetadata,
|
||||
DependencyProvider
|
||||
} from 'angular2/di';
|
||||
import {
|
||||
|
@ -167,9 +166,10 @@ export class TreeNode<T extends TreeNode<any>> {
|
|||
}
|
||||
|
||||
export class DirectiveDependency extends Dependency {
|
||||
constructor(key: Key, optional: boolean, visibility: any, properties: List<any>,
|
||||
public attributeName: string, public queryDecorator: Query) {
|
||||
super(key, optional, visibility, properties);
|
||||
constructor(key: Key, optional: boolean, lowerBoundVisibility: Object,
|
||||
upperBoundVisibility: Object, properties: List<any>, public attributeName: string,
|
||||
public queryDecorator: Query) {
|
||||
super(key, optional, lowerBoundVisibility, upperBoundVisibility, properties);
|
||||
this._verify();
|
||||
}
|
||||
|
||||
|
@ -183,9 +183,9 @@ export class DirectiveDependency extends Dependency {
|
|||
}
|
||||
|
||||
static createFrom(d: Dependency): Dependency {
|
||||
return new DirectiveDependency(d.key, d.optional, d.visibility, d.properties,
|
||||
DirectiveDependency._attributeName(d.properties),
|
||||
DirectiveDependency._query(d.properties));
|
||||
return new DirectiveDependency(
|
||||
d.key, d.optional, d.lowerBoundVisibility, d.upperBoundVisibility, d.properties,
|
||||
DirectiveDependency._attributeName(d.properties), DirectiveDependency._query(d.properties));
|
||||
}
|
||||
|
||||
static _attributeName(properties): string {
|
||||
|
|
|
@ -14,9 +14,10 @@ import {Key} from './key';
|
|||
import {
|
||||
InjectMetadata,
|
||||
InjectableMetadata,
|
||||
VisibilityMetadata,
|
||||
OptionalMetadata,
|
||||
DEFAULT_VISIBILITY,
|
||||
SelfMetadata,
|
||||
HostMetadata,
|
||||
SkipSelfMetadata,
|
||||
DependencyMetadata
|
||||
} from './metadata';
|
||||
import {NoAnnotationError} from './exceptions';
|
||||
|
@ -26,12 +27,10 @@ import {resolveForwardRef} from './forward_ref';
|
|||
* @private
|
||||
*/
|
||||
export class Dependency {
|
||||
constructor(public key: Key, public optional: boolean, public visibility: VisibilityMetadata,
|
||||
public properties: List<any>) {}
|
||||
constructor(public key: Key, public optional: boolean, public lowerBoundVisibility: any,
|
||||
public upperBoundVisibility: any, public properties: List<any>) {}
|
||||
|
||||
static fromKey(key: Key): Dependency {
|
||||
return new Dependency(key, false, DEFAULT_VISIBILITY, []);
|
||||
}
|
||||
static fromKey(key: Key): Dependency { return new Dependency(key, false, null, null, []); }
|
||||
}
|
||||
|
||||
const _EMPTY_LIST = CONST_EXPR([]);
|
||||
|
@ -390,50 +389,61 @@ function _dependenciesFor(typeOrFunc): List<Dependency> {
|
|||
return ListWrapper.map(params, (p: List<any>) => _extractToken(typeOrFunc, p, params));
|
||||
}
|
||||
|
||||
function _extractToken(typeOrFunc, annotations /*List<any> | any*/, params: List<List<any>>):
|
||||
function _extractToken(typeOrFunc, metadata /*List<any> | any*/, params: List<List<any>>):
|
||||
Dependency {
|
||||
var depProps = [];
|
||||
var token = null;
|
||||
var optional = false;
|
||||
|
||||
if (!isArray(annotations)) {
|
||||
return _createDependency(annotations, optional, DEFAULT_VISIBILITY, depProps);
|
||||
if (!isArray(metadata)) {
|
||||
return _createDependency(metadata, optional, null, null, depProps);
|
||||
}
|
||||
|
||||
var visibility = DEFAULT_VISIBILITY;
|
||||
var lowerBoundVisibility = null;
|
||||
;
|
||||
var upperBoundVisibility = null;
|
||||
;
|
||||
|
||||
for (var i = 0; i < annotations.length; ++i) {
|
||||
var paramAnnotation = annotations[i];
|
||||
for (var i = 0; i < metadata.length; ++i) {
|
||||
var paramMetadata = metadata[i];
|
||||
|
||||
if (paramAnnotation instanceof Type) {
|
||||
token = paramAnnotation;
|
||||
if (paramMetadata instanceof Type) {
|
||||
token = paramMetadata;
|
||||
|
||||
} else if (paramAnnotation instanceof InjectMetadata) {
|
||||
token = paramAnnotation.token;
|
||||
} else if (paramMetadata instanceof InjectMetadata) {
|
||||
token = paramMetadata.token;
|
||||
|
||||
} else if (paramAnnotation instanceof OptionalMetadata) {
|
||||
} else if (paramMetadata instanceof OptionalMetadata) {
|
||||
optional = true;
|
||||
|
||||
} else if (paramAnnotation instanceof VisibilityMetadata) {
|
||||
visibility = paramAnnotation;
|
||||
} else if (paramMetadata instanceof SelfMetadata) {
|
||||
upperBoundVisibility = paramMetadata;
|
||||
|
||||
} else if (paramAnnotation instanceof DependencyMetadata) {
|
||||
if (isPresent(paramAnnotation.token)) {
|
||||
token = paramAnnotation.token;
|
||||
} else if (paramMetadata instanceof HostMetadata) {
|
||||
upperBoundVisibility = paramMetadata;
|
||||
|
||||
} else if (paramMetadata instanceof SkipSelfMetadata) {
|
||||
lowerBoundVisibility = paramMetadata;
|
||||
|
||||
} else if (paramMetadata instanceof DependencyMetadata) {
|
||||
if (isPresent(paramMetadata.token)) {
|
||||
token = paramMetadata.token;
|
||||
}
|
||||
depProps.push(paramAnnotation);
|
||||
depProps.push(paramMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
token = resolveForwardRef(token);
|
||||
|
||||
if (isPresent(token)) {
|
||||
return _createDependency(token, optional, visibility, depProps);
|
||||
return _createDependency(token, optional, lowerBoundVisibility, upperBoundVisibility, depProps);
|
||||
} else {
|
||||
throw new NoAnnotationError(typeOrFunc, params);
|
||||
}
|
||||
}
|
||||
|
||||
function _createDependency(token, optional, visibility, depProps): Dependency {
|
||||
return new Dependency(Key.get(token), optional, visibility, depProps);
|
||||
function _createDependency(token, optional, lowerBoundVisibility, upperBoundVisibility, depProps):
|
||||
Dependency {
|
||||
return new Dependency(Key.get(token), optional, lowerBoundVisibility, upperBoundVisibility,
|
||||
depProps);
|
||||
}
|
||||
|
|
|
@ -32,15 +32,15 @@ class Self extends SelfMetadata {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@link AncestorMetadata}.
|
||||
* {@link HostMetadata}.
|
||||
*/
|
||||
class Ancestor extends AncestorMetadata {
|
||||
const Ancestor({bool self}) : super(self: self);
|
||||
class Host extends HostMetadata {
|
||||
const Host() : super();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link UnboundedMetadata}.
|
||||
* {@link SkipSelfMetadata}.
|
||||
*/
|
||||
class Unbounded extends UnboundedMetadata {
|
||||
const Unbounded({bool self}) : super(self: self);
|
||||
class SkipSelf extends SkipSelfMetadata {
|
||||
const SkipSelf() : super();
|
||||
}
|
||||
|
|
|
@ -3,9 +3,8 @@ import {
|
|||
OptionalMetadata,
|
||||
InjectableMetadata,
|
||||
SelfMetadata,
|
||||
VisibilityMetadata,
|
||||
AncestorMetadata,
|
||||
UnboundedMetadata
|
||||
HostMetadata,
|
||||
SkipSelfMetadata
|
||||
} from './metadata';
|
||||
import {makeDecorator, makeParamDecorator, TypeDecorator} from '../util/decorators';
|
||||
|
||||
|
@ -42,19 +41,19 @@ export interface SelfFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* Factory for creating {@link AncestorMetadata}.
|
||||
* Factory for creating {@link HostMetadata}.
|
||||
*/
|
||||
export interface AncestorFactory {
|
||||
(visibility?: {self: boolean}): any;
|
||||
new (visibility?: {self: boolean}): AncestorMetadata;
|
||||
export interface HostFactory {
|
||||
(): any;
|
||||
new (): HostMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory for creating {@link UnboundedMetadata}.
|
||||
* Factory for creating {@link SkipSelfMetadata}.
|
||||
*/
|
||||
export interface UnboundedFactory {
|
||||
(visibility?: {self: boolean}): any;
|
||||
new (visibility?: {self: boolean}): UnboundedMetadata;
|
||||
export interface SkipSelfFactory {
|
||||
(): any;
|
||||
new (): SkipSelfMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,11 +77,11 @@ export var Injectable: InjectableFactory = <InjectableFactory>makeDecorator(Inje
|
|||
export var Self: SelfFactory = makeParamDecorator(SelfMetadata);
|
||||
|
||||
/**
|
||||
* Factory for creating {@link AncestorMetadata}.
|
||||
* Factory for creating {@link HostMetadata}.
|
||||
*/
|
||||
export var Ancestor: AncestorFactory = makeParamDecorator(AncestorMetadata);
|
||||
export var Host: HostFactory = makeParamDecorator(HostMetadata);
|
||||
|
||||
/**
|
||||
* Factory for creating {@link UnboundedMetadata}.
|
||||
* Factory for creating {@link SkipSelfMetadata}.
|
||||
*/
|
||||
export var Unbounded: UnboundedFactory = makeParamDecorator(UnboundedMetadata);
|
||||
export var SkipSelf: SkipSelfFactory = makeParamDecorator(SkipSelfMetadata);
|
|
@ -13,7 +13,7 @@ import {
|
|||
import {FunctionWrapper, Type, isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
import {Key} from './key';
|
||||
import {resolveForwardRef} from './forward_ref';
|
||||
import {VisibilityMetadata, DEFAULT_VISIBILITY, SelfMetadata, AncestorMetadata} from './metadata';
|
||||
import {SelfMetadata, HostMetadata, SkipSelfMetadata} from './metadata';
|
||||
|
||||
const _constructing = CONST_EXPR(new Object());
|
||||
const _notFound = CONST_EXPR(new Object());
|
||||
|
@ -192,7 +192,7 @@ export interface InjectorStrategy {
|
|||
getObjAtIndex(index: number): any;
|
||||
getMaxNumberOfObjects(): number;
|
||||
|
||||
attach(parent: Injector, isBoundary: boolean): void;
|
||||
attach(parent: Injector, isHost: boolean): void;
|
||||
resetConstructionCounter(): void;
|
||||
instantiateBinding(binding: ResolvedBinding, visibility: number): any;
|
||||
}
|
||||
|
@ -217,10 +217,10 @@ export class InjectorInlineStrategy implements InjectorStrategy {
|
|||
return this.injector._new(binding, visibility);
|
||||
}
|
||||
|
||||
attach(parent: Injector, isBoundary: boolean): void {
|
||||
attach(parent: Injector, isHost: boolean): void {
|
||||
var inj = this.injector;
|
||||
inj._parent = parent;
|
||||
inj._isBoundary = isBoundary;
|
||||
inj._isHost = isHost;
|
||||
}
|
||||
|
||||
getObjByKeyId(keyId: number, visibility: number): any {
|
||||
|
@ -323,10 +323,10 @@ export class InjectorDynamicStrategy implements InjectorStrategy {
|
|||
return this.injector._new(binding, visibility);
|
||||
}
|
||||
|
||||
attach(parent: Injector, isBoundary: boolean): void {
|
||||
attach(parent: Injector, isHost: boolean): void {
|
||||
var inj = this.injector;
|
||||
inj._parent = parent;
|
||||
inj._isBoundary = isBoundary;
|
||||
inj._isHost = isHost;
|
||||
}
|
||||
|
||||
getObjByKeyId(keyId: number, visibility: number): any {
|
||||
|
@ -466,7 +466,7 @@ export class Injector {
|
|||
}
|
||||
|
||||
_strategy: InjectorStrategy;
|
||||
_isBoundary: boolean = false;
|
||||
_isHost: boolean = false;
|
||||
_constructionCounter: number = 0;
|
||||
|
||||
constructor(public _proto: ProtoInjector, public _parent: Injector = null,
|
||||
|
@ -490,7 +490,7 @@ export class Injector {
|
|||
* @returns an instance represented by the token. Throws if not found.
|
||||
*/
|
||||
get(token: any): any {
|
||||
return this._getByKey(Key.get(token), DEFAULT_VISIBILITY, false, PUBLIC_AND_PRIVATE);
|
||||
return this._getByKey(Key.get(token), null, null, false, PUBLIC_AND_PRIVATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -500,7 +500,7 @@ export class Injector {
|
|||
* @returns an instance represented by the token. Returns `null` if not found.
|
||||
*/
|
||||
getOptional(token: any): any {
|
||||
return this._getByKey(Key.get(token), DEFAULT_VISIBILITY, true, PUBLIC_AND_PRIVATE);
|
||||
return this._getByKey(Key.get(token), null, null, true, PUBLIC_AND_PRIVATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -679,24 +679,25 @@ export class Injector {
|
|||
if (special !== undefinedValue) {
|
||||
return special;
|
||||
} else {
|
||||
return this._getByKey(dep.key, dep.visibility, dep.optional, bindingVisibility);
|
||||
return this._getByKey(dep.key, dep.lowerBoundVisibility, dep.upperBoundVisibility,
|
||||
dep.optional, bindingVisibility);
|
||||
}
|
||||
}
|
||||
|
||||
private _getByKey(key: Key, depVisibility: VisibilityMetadata, optional: boolean,
|
||||
bindingVisibility: number): any {
|
||||
private _getByKey(key: Key, lowerBoundVisibility: Object, upperBoundVisibility: Object,
|
||||
optional: boolean, bindingVisibility: number): any {
|
||||
if (key === INJECTOR_KEY) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (depVisibility instanceof SelfMetadata) {
|
||||
if (upperBoundVisibility instanceof SelfMetadata) {
|
||||
return this._getByKeySelf(key, optional, bindingVisibility);
|
||||
|
||||
} else if (depVisibility instanceof AncestorMetadata) {
|
||||
return this._getByKeyAncestor(key, optional, bindingVisibility, depVisibility.includeSelf);
|
||||
} else if (upperBoundVisibility instanceof HostMetadata) {
|
||||
return this._getByKeyHost(key, optional, bindingVisibility, lowerBoundVisibility);
|
||||
|
||||
} else {
|
||||
return this._getByKeyUnbounded(key, optional, bindingVisibility, depVisibility.includeSelf);
|
||||
return this._getByKeyDefault(key, optional, bindingVisibility, lowerBoundVisibility);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,12 +714,12 @@ export class Injector {
|
|||
return (obj !== undefinedValue) ? obj : this._throwOrNull(key, optional);
|
||||
}
|
||||
|
||||
_getByKeyAncestor(key: Key, optional: boolean, bindingVisibility: number,
|
||||
includeSelf: boolean): any {
|
||||
_getByKeyHost(key: Key, optional: boolean, bindingVisibility: number,
|
||||
lowerBoundVisibility: Object): any {
|
||||
var inj = this;
|
||||
|
||||
if (!includeSelf) {
|
||||
if (inj._isBoundary) {
|
||||
if (lowerBoundVisibility instanceof SkipSelfMetadata) {
|
||||
if (inj._isHost) {
|
||||
return this._getPrivateDependency(key, optional, inj);
|
||||
} else {
|
||||
inj = inj._parent;
|
||||
|
@ -729,7 +730,7 @@ export class Injector {
|
|||
var obj = inj._strategy.getObjByKeyId(key.id, bindingVisibility);
|
||||
if (obj !== undefinedValue) return obj;
|
||||
|
||||
if (isPresent(inj._parent) && inj._isBoundary) {
|
||||
if (isPresent(inj._parent) && inj._isHost) {
|
||||
return this._getPrivateDependency(key, optional, inj);
|
||||
} else {
|
||||
inj = inj._parent;
|
||||
|
@ -744,11 +745,12 @@ export class Injector {
|
|||
return (obj !== undefinedValue) ? obj : this._throwOrNull(key, optional);
|
||||
}
|
||||
|
||||
_getByKeyUnbounded(key: Key, optional: boolean, bindingVisibility: number,
|
||||
includeSelf: boolean): any {
|
||||
_getByKeyDefault(key: Key, optional: boolean, bindingVisibility: number,
|
||||
lowerBoundVisibility: Object): any {
|
||||
var inj = this;
|
||||
if (!includeSelf) {
|
||||
bindingVisibility = inj._isBoundary ? PUBLIC_AND_PRIVATE : PUBLIC;
|
||||
|
||||
if (lowerBoundVisibility instanceof SkipSelfMetadata) {
|
||||
bindingVisibility = inj._isHost ? PUBLIC_AND_PRIVATE : PUBLIC;
|
||||
inj = inj._parent;
|
||||
}
|
||||
|
||||
|
@ -756,7 +758,7 @@ export class Injector {
|
|||
var obj = inj._strategy.getObjByKeyId(key.id, bindingVisibility);
|
||||
if (obj !== undefinedValue) return obj;
|
||||
|
||||
bindingVisibility = inj._isBoundary ? PUBLIC_AND_PRIVATE : PUBLIC;
|
||||
bindingVisibility = inj._isHost ? PUBLIC_AND_PRIVATE : PUBLIC;
|
||||
inj = inj._parent;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,22 +82,6 @@ export class InjectableMetadata {
|
|||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how injector should resolve a dependency.
|
||||
*
|
||||
* See {@link Self}, {@link Ancestor}, {@link Unbounded}.
|
||||
*/
|
||||
@CONST()
|
||||
export class VisibilityMetadata {
|
||||
constructor(public crossBoundaries: boolean, public _includeSelf: boolean) {}
|
||||
|
||||
get includeSelf(): boolean { return isBlank(this._includeSelf) ? false : this._includeSelf; }
|
||||
|
||||
toString(): string {
|
||||
return `@Visibility(crossBoundaries: ${this.crossBoundaries}, includeSelf: ${this.includeSelf}})`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that an injector should retrieve a dependency from itself.
|
||||
*
|
||||
|
@ -117,50 +101,45 @@ export class VisibilityMetadata {
|
|||
* ```
|
||||
*/
|
||||
@CONST()
|
||||
export class SelfMetadata extends VisibilityMetadata {
|
||||
constructor() { super(false, true); }
|
||||
export class SelfMetadata {
|
||||
toString(): string { return `@Self()`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that an injector should retrieve a dependency from any ancestor from the same boundary.
|
||||
* Specifies that the dependency resolution should start from the parent injector.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
*
|
||||
* ```
|
||||
* class Dependency {
|
||||
* class Service {}
|
||||
*
|
||||
* class ParentService implements Service {
|
||||
* }
|
||||
*
|
||||
* class NeedsDependency {
|
||||
* constructor(public @Ancestor() dependency:Dependency) {}
|
||||
* class ChildService implements Service {
|
||||
* constructor(public @SkipSelf() parentService:Service) {}
|
||||
* }
|
||||
*
|
||||
* var parent = Injector.resolveAndCreate([
|
||||
* bind(Dependency).toClass(AncestorDependency)
|
||||
* bind(Service).toClass(ParentService)
|
||||
* ]);
|
||||
* var child = parent.resolveAndCreateChild([]);
|
||||
* var grandChild = child.resolveAndCreateChild([NeedsDependency, Depedency]);
|
||||
* var nd = grandChild.get(NeedsDependency);
|
||||
* expect(nd.dependency).toBeAnInstanceOf(AncestorDependency);
|
||||
* ```
|
||||
*
|
||||
* You can make an injector to retrive a dependency either from itself or its ancestor by setting
|
||||
* self to true.
|
||||
*
|
||||
* ```
|
||||
* class NeedsDependency {
|
||||
* constructor(public @Ancestor({self:true}) dependency:Dependency) {}
|
||||
* }
|
||||
* var child = parent.resolveAndCreateChild([
|
||||
* bind(Service).toClass(ChildSerice)
|
||||
* ]);
|
||||
* var s = child.get(Service);
|
||||
* expect(s).toBeAnInstanceOf(ChildService);
|
||||
* expect(s.parentService).toBeAnInstanceOf(ParentService);
|
||||
* ```
|
||||
*/
|
||||
@CONST()
|
||||
export class AncestorMetadata extends VisibilityMetadata {
|
||||
constructor({self}: {self?: boolean} = {}) { super(false, self); }
|
||||
toString(): string { return `@Ancestor(self: ${this.includeSelf}})`; }
|
||||
export class SkipSelfMetadata {
|
||||
toString(): string { return `@SkipSelf()`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies that an injector should retrieve a dependency from any ancestor, crossing boundaries.
|
||||
* Specifies that an injector should retrieve a dependency from any injector until reaching the
|
||||
* closest host.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
|
@ -169,32 +148,20 @@ export class AncestorMetadata extends VisibilityMetadata {
|
|||
* }
|
||||
*
|
||||
* class NeedsDependency {
|
||||
* constructor(public @Ancestor() dependency:Dependency) {}
|
||||
* constructor(public @Host() dependency:Dependency) {}
|
||||
* }
|
||||
*
|
||||
* var parent = Injector.resolveAndCreate([
|
||||
* bind(Dependency).toClass(AncestorDependency)
|
||||
* bind(Dependency).toClass(HostDependency)
|
||||
* ]);
|
||||
* var child = parent.resolveAndCreateChild([]);
|
||||
* var grandChild = child.resolveAndCreateChild([NeedsDependency, Depedency]);
|
||||
* var nd = grandChild.get(NeedsDependency);
|
||||
* expect(nd.dependency).toBeAnInstanceOf(AncestorDependency);
|
||||
* expect(nd.dependency).toBeAnInstanceOf(HostDependency);
|
||||
* ```
|
||||
*
|
||||
* You can make an injector to retrive a dependency either from itself or its ancestor by setting
|
||||
* self to true.
|
||||
*
|
||||
* ```
|
||||
* class NeedsDependency {
|
||||
* constructor(public @Ancestor({self:true}) dependency:Dependency) {}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@CONST()
|
||||
export class UnboundedMetadata extends VisibilityMetadata {
|
||||
constructor({self}: {self?: boolean} = {}) { super(true, self); }
|
||||
toString(): string { return `@Unbounded(self: ${this.includeSelf}})`; }
|
||||
export class HostMetadata {
|
||||
toString(): string { return `@Host()`; }
|
||||
}
|
||||
|
||||
export const DEFAULT_VISIBILITY: VisibilityMetadata =
|
||||
CONST_EXPR(new UnboundedMetadata({self: true}));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Directive} from 'angular2/annotations';
|
||||
import {Ancestor} from 'angular2/di';
|
||||
import {Host} from 'angular2/di';
|
||||
import {ViewContainerRef, TemplateRef} from 'angular2/core';
|
||||
import {isPresent, isBlank, normalizeBlank} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper, List, MapWrapper, Map} from 'angular2/src/facade/collection';
|
||||
|
@ -157,7 +157,7 @@ export class NgSwitchWhen {
|
|||
_view: SwitchView;
|
||||
|
||||
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef,
|
||||
@Ancestor() sswitch: NgSwitch) {
|
||||
@Host() sswitch: NgSwitch) {
|
||||
// `_whenDefault` is used as a marker for a not yet initialized value
|
||||
this._value = _whenDefault;
|
||||
this._switch = sswitch;
|
||||
|
@ -187,7 +187,7 @@ export class NgSwitchWhen {
|
|||
@Directive({selector: '[ng-switch-default]'})
|
||||
export class NgSwitchDefault {
|
||||
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef,
|
||||
@Ancestor() sswitch: NgSwitch) {
|
||||
@Host() sswitch: NgSwitch) {
|
||||
sswitch._registerView(_whenDefault, new SwitchView(viewContainer, templateRef));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Directive, LifecycleEvent} from 'angular2/annotations';
|
||||
import {Inject, Ancestor, forwardRef, Binding} from 'angular2/di';
|
||||
import {Inject, Host, SkipSelf, forwardRef, Binding} from 'angular2/di';
|
||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
|
@ -57,7 +57,7 @@ const controlGroupBinding =
|
|||
})
|
||||
export class NgControlGroup extends ControlContainer {
|
||||
_parent: ControlContainer;
|
||||
constructor(@Ancestor() _parent: ControlContainer) {
|
||||
constructor(@Host() @SkipSelf() _parent: ControlContainer) {
|
||||
super();
|
||||
this._parent = _parent;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import {List, StringMap} from 'angular2/src/facade/collection';
|
|||
|
||||
import {QueryList} from 'angular2/core';
|
||||
import {Query, Directive, LifecycleEvent} from 'angular2/annotations';
|
||||
import {forwardRef, Ancestor, Binding, Inject} from 'angular2/di';
|
||||
import {forwardRef, Host, SkipSelf, Binding, Inject} from 'angular2/di';
|
||||
|
||||
import {ControlContainer} from './control_container';
|
||||
import {NgControl} from './ng_control';
|
||||
|
@ -88,7 +88,7 @@ export class NgControlName extends NgControl {
|
|||
_added = false;
|
||||
|
||||
// Scope the query once https://github.com/angular/angular/issues/2603 is fixed
|
||||
constructor(@Ancestor() parent: ControlContainer,
|
||||
constructor(@Host() @SkipSelf() parent: ControlContainer,
|
||||
@Query(NgValidator) ngValidators: QueryList<NgValidator>) {
|
||||
super();
|
||||
this._parent = parent;
|
||||
|
|
|
@ -3,7 +3,7 @@ import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
|||
|
||||
import {QueryList} from 'angular2/core';
|
||||
import {Query, Directive, LifecycleEvent} from 'angular2/annotations';
|
||||
import {forwardRef, Ancestor, Binding} from 'angular2/di';
|
||||
import {forwardRef, Binding} from 'angular2/di';
|
||||
|
||||
import {NgControl} from './ng_control';
|
||||
import {Control} from '../model';
|
||||
|
|
|
@ -3,7 +3,7 @@ import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
|||
|
||||
import {QueryList} from 'angular2/core';
|
||||
import {Query, Directive, LifecycleEvent} from 'angular2/annotations';
|
||||
import {forwardRef, Ancestor, Binding} from 'angular2/di';
|
||||
import {forwardRef, Binding} from 'angular2/di';
|
||||
|
||||
import {NgControl} from './ng_control';
|
||||
import {Control} from '../model';
|
||||
|
|
|
@ -40,7 +40,7 @@ import {
|
|||
Directive,
|
||||
LifecycleEvent
|
||||
} from 'angular2/annotations';
|
||||
import {bind, Injector, Binding, Optional, Inject, Injectable, Self, Ancestor, Unbounded, InjectMetadata, AncestorMetadata} from 'angular2/di';
|
||||
import {bind, Injector, Binding, Optional, Inject, Injectable, Self, SkipSelf, InjectMetadata, Host, HostMetadata, SkipSelfMetadata} from 'angular2/di';
|
||||
import {AppProtoView, AppView} from 'angular2/src/core/compiler/view';
|
||||
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
|
||||
import {TemplateRef} from 'angular2/src/core/compiler/template_ref';
|
||||
|
@ -103,15 +103,15 @@ class OptionallyNeedsDirective {
|
|||
}
|
||||
|
||||
@Injectable()
|
||||
class NeedsDirectiveFromAncestor {
|
||||
class NeeedsDirectiveFromHost {
|
||||
dependency: SimpleDirective;
|
||||
constructor(@Ancestor() dependency: SimpleDirective) { this.dependency = dependency; }
|
||||
constructor(@Host() dependency: SimpleDirective) { this.dependency = dependency; }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class NeedsDirectiveFromAnAncestorShadowDom {
|
||||
class NeedsDirectiveFromHostShadowDom {
|
||||
dependency: SimpleDirective;
|
||||
constructor(@Unbounded() dependency: SimpleDirective) { this.dependency = dependency; }
|
||||
constructor(dependency: SimpleDirective) { this.dependency = dependency; }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
|
@ -121,9 +121,9 @@ class NeedsService {
|
|||
}
|
||||
|
||||
@Injectable()
|
||||
class NeedsAncestorService {
|
||||
class NeedsServiceFromHost {
|
||||
service: any;
|
||||
constructor(@Ancestor() @Inject("service") service) { this.service = service; }
|
||||
constructor(@Host() @Inject("service") service) { this.service = service; }
|
||||
}
|
||||
|
||||
class HasEventEmitter {
|
||||
|
@ -597,7 +597,7 @@ export function main() {
|
|||
bind('injectable2')
|
||||
.toFactory(
|
||||
(val) => `${val}-injectable2`,
|
||||
[[new InjectMetadata('injectable1'), new AncestorMetadata()]])
|
||||
[[new InjectMetadata('injectable1'), new SkipSelfMetadata()]])
|
||||
]
|
||||
}))]);
|
||||
expect(childInj.get('injectable2')).toEqual('injectable1-injectable2');
|
||||
|
@ -710,25 +710,25 @@ export function main() {
|
|||
var inj = injector([NeedsService], imperativelyCreatedInjector);
|
||||
expect(inj.get(NeedsService).service).toEqual('appService');
|
||||
|
||||
expect(() => injector([NeedsAncestorService], imperativelyCreatedInjector)).toThrowError();
|
||||
expect(() => injector([NeedsServiceFromHost], imperativelyCreatedInjector)).toThrowError();
|
||||
});
|
||||
|
||||
it("should instantiate directives that depend on imperatively created injector bindings (root injector)", () => {
|
||||
var imperativelyCreatedInjector = Injector.resolveAndCreate([
|
||||
bind("service").toValue('appService')
|
||||
]);
|
||||
var inj = hostShadowInjectors([SimpleDirective], [NeedsService, NeedsAncestorService], imperativelyCreatedInjector);
|
||||
var inj = hostShadowInjectors([SimpleDirective], [NeedsService, NeedsServiceFromHost], imperativelyCreatedInjector);
|
||||
expect(inj.get(NeedsService).service).toEqual('appService');
|
||||
expect(inj.get(NeedsAncestorService).service).toEqual('appService');
|
||||
expect(inj.get(NeedsServiceFromHost).service).toEqual('appService');
|
||||
});
|
||||
|
||||
it("should instantiate directives that depend on imperatively created injector bindings (child injector)", () => {
|
||||
var imperativelyCreatedInjector = Injector.resolveAndCreate([
|
||||
bind("service").toValue('appService')
|
||||
]);
|
||||
var inj = parentChildInjectors([], [NeedsService, NeedsAncestorService], null, imperativelyCreatedInjector);
|
||||
var inj = parentChildInjectors([], [NeedsService, NeedsServiceFromHost], null, imperativelyCreatedInjector);
|
||||
expect(inj.get(NeedsService).service).toEqual('appService');
|
||||
expect(inj.get(NeedsAncestorService).service).toEqual('appService');
|
||||
expect(inj.get(NeedsServiceFromHost).service).toEqual('appService');
|
||||
});
|
||||
|
||||
it("should prioritize viewInjector over hostInjector for the same binding", () => {
|
||||
|
@ -750,7 +750,7 @@ export function main() {
|
|||
hostInjector: [bind('service').toValue('hostService')]})
|
||||
)], extraBindings),
|
||||
|
||||
ListWrapper.concat([NeedsAncestorService], extraBindings)
|
||||
ListWrapper.concat([NeedsServiceFromHost], extraBindings)
|
||||
);
|
||||
}).toThrowError(new RegExp("No provider for service!"));
|
||||
});
|
||||
|
@ -763,31 +763,31 @@ export function main() {
|
|||
expect(inj.get(NeedsTemplateRef).templateRef).toEqual(templateRef);
|
||||
});
|
||||
|
||||
it("should get directives from ancestor", () => {
|
||||
var child = parentChildInjectors(ListWrapper.concat([SimpleDirective], extraBindings),
|
||||
[NeedsDirectiveFromAncestor]);
|
||||
it("should get directives", () => {
|
||||
var child = hostShadowInjectors(
|
||||
ListWrapper.concat([SomeOtherDirective, SimpleDirective], extraBindings),
|
||||
[NeedsDirectiveFromHostShadowDom]);
|
||||
|
||||
var d = child.get(NeedsDirectiveFromAncestor);
|
||||
var d = child.get(NeedsDirectiveFromHostShadowDom);
|
||||
|
||||
expect(d).toBeAnInstanceOf(NeedsDirectiveFromAncestor);
|
||||
expect(d).toBeAnInstanceOf(NeedsDirectiveFromHostShadowDom);
|
||||
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
|
||||
});
|
||||
|
||||
it("should get directives crossing the boundaries", () => {
|
||||
var child = hostShadowInjectors(
|
||||
ListWrapper.concat([SomeOtherDirective, SimpleDirective], extraBindings),
|
||||
[NeedsDirectiveFromAnAncestorShadowDom]);
|
||||
it("should get directives from the host", () => {
|
||||
var child = parentChildInjectors(ListWrapper.concat([SimpleDirective], extraBindings),
|
||||
[NeeedsDirectiveFromHost]);
|
||||
|
||||
var d = child.get(NeedsDirectiveFromAnAncestorShadowDom);
|
||||
var d = child.get(NeeedsDirectiveFromHost);
|
||||
|
||||
expect(d).toBeAnInstanceOf(NeedsDirectiveFromAnAncestorShadowDom);
|
||||
expect(d).toBeAnInstanceOf(NeeedsDirectiveFromHost);
|
||||
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
|
||||
});
|
||||
|
||||
it("should throw when a dependency cannot be resolved", () => {
|
||||
expect(() => injector(ListWrapper.concat([NeedsDirectiveFromAncestor], extraBindings)))
|
||||
expect(() => injector(ListWrapper.concat([NeeedsDirectiveFromHost], extraBindings)))
|
||||
.toThrowError(containsRegexp(
|
||||
`No provider for ${stringify(SimpleDirective) }! (${stringify(NeedsDirectiveFromAncestor) } -> ${stringify(SimpleDirective) })`));
|
||||
`No provider for ${stringify(SimpleDirective) }! (${stringify(NeeedsDirectiveFromHost) } -> ${stringify(SimpleDirective) })`));
|
||||
});
|
||||
|
||||
it("should inject null when an optional dependency cannot be resolved", () => {
|
||||
|
@ -820,10 +820,10 @@ export function main() {
|
|||
var directiveBinding =
|
||||
DirectiveBinding.createFromType(SimpleDirective, new dirAnn.Component());
|
||||
var shadow = hostShadowInjectors(ListWrapper.concat([directiveBinding], extraBindings),
|
||||
[NeedsDirectiveFromAncestor]);
|
||||
[NeeedsDirectiveFromHost]);
|
||||
|
||||
var d = shadow.get(NeedsDirectiveFromAncestor);
|
||||
expect(d).toBeAnInstanceOf(NeedsDirectiveFromAncestor);
|
||||
var d = shadow.get(NeeedsDirectiveFromHost);
|
||||
expect(d).toBeAnInstanceOf(NeeedsDirectiveFromHost);
|
||||
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
|
||||
});
|
||||
|
||||
|
|
|
@ -44,9 +44,9 @@ import {
|
|||
forwardRef,
|
||||
OpaqueToken,
|
||||
Inject,
|
||||
Ancestor,
|
||||
Unbounded,
|
||||
UnboundedMetadata
|
||||
Host,
|
||||
SkipSelf,
|
||||
SkipSelfMetadata
|
||||
} from 'angular2/di';
|
||||
import {
|
||||
PipeFactory,
|
||||
|
@ -435,8 +435,8 @@ export function main() {
|
|||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new viewAnn.View({
|
||||
template:
|
||||
'<some-directive><toolbar><template toolbarpart var-toolbar-prop="toolbarProp">{{ctxProp}},{{toolbarProp}},<cmp-with-ancestor></cmp-with-ancestor></template></toolbar></some-directive>',
|
||||
directives: [SomeDirective, CompWithAncestor, ToolbarComponent, ToolbarPart]
|
||||
'<some-directive><toolbar><template toolbarpart var-toolbar-prop="toolbarProp">{{ctxProp}},{{toolbarProp}},<cmp-with-host></cmp-with-host></template></toolbar></some-directive>',
|
||||
directives: [SomeDirective, CompWithHost, ToolbarComponent, ToolbarPart]
|
||||
}))
|
||||
.createAsync(MyComp)
|
||||
.then((rootTC) => {
|
||||
|
@ -445,7 +445,7 @@ export function main() {
|
|||
|
||||
expect(rootTC.nativeElement)
|
||||
.toHaveText(
|
||||
'TOOLBAR(From myComp,From toolbar,Component with an injected ancestor)');
|
||||
'TOOLBAR(From myComp,From toolbar,Component with an injected host)');
|
||||
|
||||
async.done();
|
||||
});
|
||||
|
@ -675,38 +675,38 @@ export function main() {
|
|||
})}));
|
||||
});
|
||||
|
||||
it('should create a component that injects an @Ancestor',
|
||||
it('should create a component that injects an @Host',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter],
|
||||
(tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new viewAnn.View({
|
||||
template: `
|
||||
<some-directive>
|
||||
<p>
|
||||
<cmp-with-ancestor #child></cmp-with-ancestor>
|
||||
<cmp-with-host #child></cmp-with-host>
|
||||
</p>
|
||||
</some-directive>`,
|
||||
directives: [SomeDirective, CompWithAncestor]
|
||||
directives: [SomeDirective, CompWithHost]
|
||||
}))
|
||||
|
||||
.createAsync(MyComp)
|
||||
.then((rootTC) => {
|
||||
|
||||
var childComponent = rootTC.componentViewChildren[0].getLocal('child');
|
||||
expect(childComponent.myAncestor).toBeAnInstanceOf(SomeDirective);
|
||||
expect(childComponent.myHost).toBeAnInstanceOf(SomeDirective);
|
||||
|
||||
async.done();
|
||||
})}));
|
||||
|
||||
it('should create a component that injects an @Ancestor through viewcontainer directive',
|
||||
it('should create a component that injects an @Host through viewcontainer directive',
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
tcb.overrideView(MyComp, new viewAnn.View({
|
||||
template: `
|
||||
<some-directive>
|
||||
<p *ng-if="true">
|
||||
<cmp-with-ancestor #child></cmp-with-ancestor>
|
||||
<cmp-with-host #child></cmp-with-host>
|
||||
</p>
|
||||
</some-directive>`,
|
||||
directives: [SomeDirective, CompWithAncestor, NgIf]
|
||||
directives: [SomeDirective, CompWithHost, NgIf]
|
||||
}))
|
||||
|
||||
.createAsync(MyComp)
|
||||
|
@ -716,7 +716,7 @@ export function main() {
|
|||
var tc = rootTC.componentViewChildren[0].children[1];
|
||||
|
||||
var childComponent = tc.getLocal('child');
|
||||
expect(childComponent.myAncestor).toBeAnInstanceOf(SomeDirective);
|
||||
expect(childComponent.myHost).toBeAnInstanceOf(SomeDirective);
|
||||
|
||||
async.done();
|
||||
});
|
||||
|
@ -1607,12 +1607,12 @@ class SomeDirective {
|
|||
|
||||
class SomeDirectiveMissingAnnotation {}
|
||||
|
||||
@Component({selector: 'cmp-with-ancestor'})
|
||||
@View({template: '<p>Component with an injected ancestor</p>', directives: [SomeDirective]})
|
||||
@Component({selector: 'cmp-with-host'})
|
||||
@View({template: '<p>Component with an injected host</p>', directives: [SomeDirective]})
|
||||
@Injectable()
|
||||
class CompWithAncestor {
|
||||
myAncestor: SomeDirective;
|
||||
constructor(@Ancestor() someComp: SomeDirective) { this.myAncestor = someComp; }
|
||||
class CompWithHost {
|
||||
myHost: SomeDirective;
|
||||
constructor(@Host() someComp: SomeDirective) { this.myHost = someComp; }
|
||||
}
|
||||
|
||||
@Component({selector: '[child-cmp2]', viewInjector: [MyService]})
|
||||
|
@ -1775,7 +1775,7 @@ class PrivateImpl extends PublicApi {
|
|||
@Directive({selector: '[needs-public-api]'})
|
||||
@Injectable()
|
||||
class NeedsPublicApi {
|
||||
constructor(@Ancestor() api: PublicApi) { expect(api instanceof PrivateImpl).toBe(true); }
|
||||
constructor(@Host() api: PublicApi) { expect(api instanceof PrivateImpl).toBe(true); }
|
||||
}
|
||||
|
||||
@Directive({selector: '[toolbarpart]'})
|
||||
|
@ -1873,7 +1873,7 @@ class DirectiveProvidingInjectableInHostAndView {
|
|||
class DirectiveConsumingInjectable {
|
||||
injectable;
|
||||
|
||||
constructor(@Ancestor() @Inject(InjectableService) injectable) { this.injectable = injectable; }
|
||||
constructor(@Host() @Inject(InjectableService) injectable) { this.injectable = injectable; }
|
||||
}
|
||||
|
||||
|
||||
|
@ -1890,8 +1890,8 @@ class DirectiveContainingDirectiveConsumingAnInjectable {
|
|||
class DirectiveConsumingInjectableUnbounded {
|
||||
injectable;
|
||||
|
||||
constructor(@Unbounded() injectable: InjectableService,
|
||||
@Ancestor() parent: DirectiveContainingDirectiveConsumingAnInjectable) {
|
||||
constructor(injectable: InjectableService,
|
||||
@SkipSelf() parent: DirectiveContainingDirectiveConsumingAnInjectable) {
|
||||
this.injectable = injectable;
|
||||
parent.directive = this;
|
||||
}
|
||||
|
@ -1927,7 +1927,7 @@ function createParentBus(peb) {
|
|||
selector: 'parent-providing-event-bus',
|
||||
hostInjector: [
|
||||
new Binding(EventBus,
|
||||
{toFactory: createParentBus, deps: [[EventBus, new UnboundedMetadata()]]})
|
||||
{toFactory: createParentBus, deps: [[EventBus, new SkipSelfMetadata()]]})
|
||||
]
|
||||
})
|
||||
@View({
|
||||
|
@ -1940,7 +1940,7 @@ class ParentProvidingEventBus {
|
|||
bus: EventBus;
|
||||
grandParentBus: EventBus;
|
||||
|
||||
constructor(bus: EventBus, @Unbounded() grandParentBus: EventBus) {
|
||||
constructor(bus: EventBus, @SkipSelf() grandParentBus: EventBus) {
|
||||
this.bus = bus;
|
||||
this.grandParentBus = grandParentBus;
|
||||
}
|
||||
|
@ -1950,7 +1950,7 @@ class ParentProvidingEventBus {
|
|||
class ChildConsumingEventBus {
|
||||
bus: EventBus;
|
||||
|
||||
constructor(@Unbounded() bus: EventBus) { this.bus = bus; }
|
||||
constructor(@SkipSelf() bus: EventBus) { this.bus = bus; }
|
||||
}
|
||||
|
||||
@Directive({selector: '[some-impvp]', properties: ['someImpvp']})
|
||||
|
|
|
@ -19,8 +19,8 @@ import {
|
|||
Injectable,
|
||||
InjectMetadata,
|
||||
SelfMetadata,
|
||||
AncestorMetadata,
|
||||
UnboundedMetadata,
|
||||
HostMetadata,
|
||||
SkipSelfMetadata,
|
||||
Optional,
|
||||
Inject,
|
||||
BindingWithVisibility,
|
||||
|
@ -420,57 +420,56 @@ export function main() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("@Ancestor()", () => {
|
||||
it("should return a dependency from same boundary", () => {
|
||||
describe("@Host()", () => {
|
||||
it("should return a dependency from same host", () => {
|
||||
var parent = Injector.resolveAndCreate([Engine]);
|
||||
var child = parent.resolveAndCreateChild(
|
||||
[bind(Car).toFactory((e) => new Car(e), [[Engine, new AncestorMetadata()]])]);
|
||||
[bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])]);
|
||||
|
||||
expect(child.get(Car)).toBeAnInstanceOf(Car);
|
||||
});
|
||||
|
||||
it("should return a private dependency declared at the boundary", () => {
|
||||
it("should return a private dependency declared at the host", () => {
|
||||
var engine = Injector.resolve([Engine])[0];
|
||||
var protoParent = new ProtoInjector([new BindingWithVisibility(engine, PRIVATE)]);
|
||||
var parent = new Injector(protoParent);
|
||||
|
||||
var child = Injector.resolveAndCreate(
|
||||
[bind(Car).toFactory((e) => new Car(e), [[Engine, new AncestorMetadata()]])]);
|
||||
[bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])]);
|
||||
|
||||
child.internalStrategy.attach(parent, true); // boundary
|
||||
child.internalStrategy.attach(parent, true); // host
|
||||
|
||||
expect(child.get(Car)).toBeAnInstanceOf(Car);
|
||||
});
|
||||
|
||||
it("should not return a public dependency declared at the boundary", () => {
|
||||
it("should not return a public dependency declared at the host", () => {
|
||||
var engine = Injector.resolve([Engine])[0];
|
||||
var protoParent = new ProtoInjector([new BindingWithVisibility(engine, PUBLIC)]);
|
||||
var parent = new Injector(protoParent);
|
||||
|
||||
var child = Injector.resolveAndCreate(
|
||||
[bind(Car).toFactory((e) => new Car(e), [[Engine, new AncestorMetadata()]])]);
|
||||
[bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])]);
|
||||
|
||||
child.internalStrategy.attach(parent, true); // boundary
|
||||
child.internalStrategy.attach(parent, true); // host
|
||||
|
||||
expect(() => child.get(Car))
|
||||
.toThrowError(`No provider for Engine! (${stringify(Car)} -> ${stringify(Engine)})`);
|
||||
});
|
||||
|
||||
it("should return a dependency from self when explicitly specified", () => {
|
||||
it("should not skip self", () => {
|
||||
var parent = Injector.resolveAndCreate([Engine]);
|
||||
var child = parent.resolveAndCreateChild([
|
||||
bind(Engine)
|
||||
.toClass(TurboEngine),
|
||||
bind(Car)
|
||||
.toFactory((e) => new Car(e), [[Engine, new AncestorMetadata({self: true})]])
|
||||
bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])
|
||||
]);
|
||||
|
||||
expect(child.get(Car).engine).toBeAnInstanceOf(TurboEngine);
|
||||
});
|
||||
});
|
||||
|
||||
describe("@Unboudned()", () => {
|
||||
it("should return a private dependency declared at the boundary", () => {
|
||||
describe("default", () => {
|
||||
it("should return a private dependency declared at the host", () => {
|
||||
var engine = Injector.resolve([Engine])[0];
|
||||
var protoParent = new ProtoInjector([new BindingWithVisibility(engine, PRIVATE)]);
|
||||
var parent = new Injector(protoParent);
|
||||
|
@ -478,14 +477,14 @@ export function main() {
|
|||
var child = Injector.resolveAndCreate([
|
||||
bind(Engine)
|
||||
.toClass(BrokenEngine),
|
||||
bind(Car).toFactory((e) => new Car(e), [[Engine, new UnboundedMetadata()]])
|
||||
bind(Car).toFactory((e) => new Car(e), [[Engine, new SkipSelfMetadata()]])
|
||||
]);
|
||||
child.internalStrategy.attach(parent, true); // boundary
|
||||
|
||||
expect(child.get(Car)).toBeAnInstanceOf(Car);
|
||||
});
|
||||
|
||||
it("should return a public dependency declared at the boundary", () => {
|
||||
it("should return a public dependency declared at the host", () => {
|
||||
var engine = Injector.resolve([Engine])[0];
|
||||
var protoParent = new ProtoInjector([new BindingWithVisibility(engine, PUBLIC)]);
|
||||
var parent = new Injector(protoParent);
|
||||
|
@ -493,14 +492,14 @@ export function main() {
|
|||
var child = Injector.resolveAndCreate([
|
||||
bind(Engine)
|
||||
.toClass(BrokenEngine),
|
||||
bind(Car).toFactory((e) => new Car(e), [[Engine, new UnboundedMetadata()]])
|
||||
bind(Car).toFactory((e) => new Car(e), [[Engine, new SkipSelfMetadata()]])
|
||||
]);
|
||||
child.internalStrategy.attach(parent, true); // boundary
|
||||
|
||||
expect(child.get(Car)).toBeAnInstanceOf(Car);
|
||||
});
|
||||
|
||||
it("should not return a private dependency declared NOT at the boundary", () => {
|
||||
it("should not return a private dependency declared NOT at the host", () => {
|
||||
var engine = Injector.resolve([Engine])[0];
|
||||
var protoParent = new ProtoInjector([new BindingWithVisibility(engine, PRIVATE)]);
|
||||
var parent = new Injector(protoParent);
|
||||
|
@ -508,7 +507,7 @@ export function main() {
|
|||
var child = Injector.resolveAndCreate([
|
||||
bind(Engine)
|
||||
.toClass(BrokenEngine),
|
||||
bind(Car).toFactory((e) => new Car(e), [[Engine, new UnboundedMetadata()]])
|
||||
bind(Car).toFactory((e) => new Car(e), [[Engine, new SkipSelfMetadata()]])
|
||||
]);
|
||||
child.internalStrategy.attach(parent, false);
|
||||
|
||||
|
@ -516,13 +515,12 @@ export function main() {
|
|||
.toThrowError(`No provider for Engine! (${stringify(Car)} -> ${stringify(Engine)})`);
|
||||
});
|
||||
|
||||
it("should return a dependency from self when explicitly specified", () => {
|
||||
it("should not skip self", () => {
|
||||
var parent = Injector.resolveAndCreate([Engine]);
|
||||
var child = parent.resolveAndCreateChild([
|
||||
bind(Engine)
|
||||
.toClass(TurboEngine),
|
||||
bind(Car)
|
||||
.toFactory((e) => new Car(e), [[Engine, new UnboundedMetadata({self: true})]])
|
||||
bind(Car).toFactory((e) => new Car(e), [Engine])
|
||||
]);
|
||||
|
||||
expect(child.get(Car).engine).toBeAnInstanceOf(TurboEngine);
|
||||
|
|
|
@ -3,7 +3,8 @@ import {
|
|||
Directive,
|
||||
View,
|
||||
ViewEncapsulation,
|
||||
Ancestor,
|
||||
Host,
|
||||
SkipSelf,
|
||||
ElementRef,
|
||||
DynamicComponentLoader,
|
||||
ComponentRef,
|
||||
|
@ -212,8 +213,7 @@ export class MdDialogConfig {
|
|||
})
|
||||
@View({
|
||||
templateUrl: 'package:angular2_material/src/components/dialog/dialog.html',
|
||||
directives: [forwardRef(() => MdDialogContent)],
|
||||
encapsulation: ViewEncapsulation.NONE
|
||||
directives: [forwardRef(() => MdDialogContent)]
|
||||
})
|
||||
class MdDialogContainer {
|
||||
// Ref to the dialog content. Used by the DynamicComponentLoader to load the dialog content.
|
||||
|
@ -245,7 +245,7 @@ class MdDialogContainer {
|
|||
*/
|
||||
@Directive({selector: 'md-dialog-content'})
|
||||
class MdDialogContent {
|
||||
constructor(@Ancestor() dialogContainer: MdDialogContainer, elementRef: ElementRef) {
|
||||
constructor(@Host() @SkipSelf() dialogContainer: MdDialogContainer, elementRef: ElementRef) {
|
||||
dialogContainer.contentRef = elementRef;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import {Component, View, ViewEncapsulation, Ancestor, LifecycleEvent} from 'angular2/angular2';
|
||||
import {
|
||||
Component,
|
||||
View,
|
||||
ViewEncapsulation,
|
||||
Host,
|
||||
SkipSelf,
|
||||
LifecycleEvent
|
||||
} from 'angular2/angular2';
|
||||
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {StringWrapper, isPresent, isString, NumberWrapper} from 'angular2/src/facade/lang';
|
||||
|
@ -244,7 +251,7 @@ export class MdGridTile {
|
|||
|
||||
isRegisteredWithGridList: boolean;
|
||||
|
||||
constructor(@Ancestor() gridList: MdGridList) {
|
||||
constructor(@SkipSelf() @Host() gridList: MdGridList) {
|
||||
this.gridList = gridList;
|
||||
|
||||
// Tiles default to 1x1, but rowspan and colspan can be changed via binding.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Directive, LifecycleEvent, Attribute, Ancestor} from 'angular2/angular2';
|
||||
import {Directive, LifecycleEvent, Attribute, Host, SkipSelf} from 'angular2/angular2';
|
||||
|
||||
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
|
||||
|
||||
|
@ -73,7 +73,7 @@ export class MdInput {
|
|||
mdChange: EventEmitter;
|
||||
mdFocusChange: EventEmitter;
|
||||
|
||||
constructor(@Attribute('value') value: string, @Ancestor() container: MdInputContainer,
|
||||
constructor(@Attribute('value') value: string, @SkipSelf() @Host() container: MdInputContainer,
|
||||
@Attribute('id') id: string) {
|
||||
// TODO(jelbourn): Remove this when #1402 is done.
|
||||
this.yes = true;
|
||||
|
@ -111,7 +111,7 @@ export class MdInput {
|
|||
export class MdTextarea extends MdInput {
|
||||
constructor(
|
||||
@Attribute('value') value: string,
|
||||
@Ancestor() container: MdInputContainer,
|
||||
@SkipSelf() @Host() container: MdInputContainer,
|
||||
@Attribute('id') id: string) {
|
||||
super(value, container, id);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@ import {
|
|||
View,
|
||||
ViewEncapsulation,
|
||||
LifecycleEvent,
|
||||
Ancestor,
|
||||
Host,
|
||||
SkipSelf,
|
||||
Attribute,
|
||||
Optional
|
||||
} from 'angular2/angular2';
|
||||
|
@ -232,7 +233,7 @@ export class MdRadioButton {
|
|||
|
||||
role: string;
|
||||
|
||||
constructor(@Optional() @Ancestor() radioGroup: MdRadioGroup, @Attribute('id') id: string,
|
||||
constructor(@Optional() @SkipSelf() @Host() radioGroup: MdRadioGroup, @Attribute('id') id: string,
|
||||
@Attribute('tabindex') tabindex: string, radioDispatcher: MdRadioDispatcher) {
|
||||
// Assertions. Ideally these should be stripped out by the compiler.
|
||||
// TODO(jelbourn): Assert that there's no name binding AND a parent radio group.
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
Component,
|
||||
Directive,
|
||||
View,
|
||||
Ancestor
|
||||
Host
|
||||
} from 'angular2/bootstrap';
|
||||
import {formDirectives, NgControl, Validators, NgFormModel, FormBuilder} from 'angular2/forms';
|
||||
|
||||
|
@ -50,7 +50,7 @@ class ShowError {
|
|||
controlPath: string;
|
||||
errorTypes: List<string>;
|
||||
|
||||
constructor(@Ancestor() formDir: NgFormModel) { this.formDir = formDir; }
|
||||
constructor(@Host() formDir: NgFormModel) { this.formDir = formDir; }
|
||||
|
||||
get errorMessage() {
|
||||
var c = this.formDir.form.find(this.controlPath);
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
Component,
|
||||
Directive,
|
||||
View,
|
||||
Ancestor,
|
||||
Host,
|
||||
NgValidator,
|
||||
forwardRef,
|
||||
Binding,
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
Component,
|
||||
Directive,
|
||||
View,
|
||||
Ancestor,
|
||||
Host,
|
||||
NgValidator,
|
||||
forwardRef,
|
||||
Binding
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
Component,
|
||||
Directive,
|
||||
View,
|
||||
Ancestor,
|
||||
Host,
|
||||
NgValidator,
|
||||
forwardRef,
|
||||
Binding
|
||||
|
@ -76,7 +76,7 @@ class ShowError {
|
|||
controlPath: string;
|
||||
errorTypes: List<string>;
|
||||
|
||||
constructor(@Ancestor() formDir: NgForm) { this.formDir = formDir; }
|
||||
constructor(@Host() formDir: NgForm) { this.formDir = formDir; }
|
||||
|
||||
get errorMessage() {
|
||||
var c = this.formDir.form.find(this.controlPath);
|
||||
|
|
Loading…
Reference in New Issue