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:
vsavkin
2015-07-29 11:26:09 -07:00
parent a9ec6b9064
commit 985627bd65
27 changed files with 246 additions and 268 deletions
@@ -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 {
+37 -27
View File
@@ -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);
}
+6 -6
View File
@@ -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();
}
+14 -15
View File
@@ -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);
+28 -26
View File
@@ -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;
}
+24 -57
View File
@@ -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}));
+3 -3
View File
@@ -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';