diff --git a/angular2/angular2-2.0.0-alpha.31.d.ts b/angular2/angular2-2.0.0-alpha.31.d.ts new file mode 100644 index 0000000000..dfad7d3494 --- /dev/null +++ b/angular2/angular2-2.0.0-alpha.31.d.ts @@ -0,0 +1,6137 @@ +// Type definitions for Angular v2.0.0-alpha.31 +// Project: http://angular.io/ +// Definitions by: angular team +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +// *********************************************************** +// This file is generated by the Angular build process. +// Please do not create manual edits or send pull requests +// modifying this file. +// *********************************************************** + +// Angular depends transitively on these libraries. +// If you don't have them installed you can run +// $ tsd query es6-promise rx rx-lite --action install --save +/// +/// + +interface List extends Array {} +interface Map {} +interface StringMap extends Map {} + +declare module ng { + type SetterFn = typeof Function; + type int = number; + interface Type extends Function { + new (...args:any[]):any; + } + + // See https://github.com/Microsoft/TypeScript/issues/1168 + class BaseException /* extends Error */ { + message: string; + stack: string; + toString(): string; + } + interface InjectableReference {} +} + + + + +/** + * The `angular2` is the single place to import all of the individual types. + */ +declare module ng { + class DehydratedException extends BaseException { + } + + class ExpressionChangedAfterItHasBeenChecked extends BaseException { + } + + class ChangeDetectionError extends BaseException { + + location: string; + } + + + /** + * ON_PUSH means that the change detector's mode will be set to CHECK_ONCE during hydration. + */ + var ON_PUSH:any; + + + /** + * DEFAULT means that the change detector's mode will be set to CHECK_ALWAYS during hydration. + */ + var DEFAULT:any; + + + /** + * Controls change detection. + * + * {@link ChangeDetectorRef} allows requesting checks for detectors that rely on observables. It + * also allows detaching and + * attaching change detector subtrees. + */ + class ChangeDetectorRef { + + + /** + * Request to check all ON_PUSH ancestors. + */ + requestCheck(): void; + + + /** + * Detaches the change detector from the change detector tree. + * + * The detached change detector will not be checked until it is reattached. + */ + detach(): void; + + + /** + * Reattach the change detector to the change detector tree. + * + * This also requests a check of this change detector. This reattached change detector will be + * checked during the + * next change detection run. + */ + reattach(): void; + } + + class Pipes { + + + /** + * Map of {@link Pipe} names to {@link PipeFactory} lists used to configure the + * {@link Pipes} registry. + * + * #Example + * + * ``` + * var pipesConfig = { + * 'json': [jsonPipeFactory] + * } + * @Component({ + * viewInjector: [ + * bind(Pipes).toValue(new Pipes(pipesConfig)) + * ] + * }) + * ``` + */ + config: StringMap; + + get(type: string, obj: any, cdRef?: ChangeDetectorRef, existingPipe?: Pipe): Pipe; + } + + + /** + * Indicates that the result of a {@link Pipe} transformation has changed even though the reference + * has not changed. + * + * The wrapped value will be unwrapped by change detection, and the unwrapped value will be stored. + */ + class WrappedValue { + + wrapped: any; + } + + + /** + * An interface for extending the list of pipes known to Angular. + * + * If you are writing a custom {@link Pipe}, you must extend this interface. + * + * #Example + * + * ``` + * class DoublePipe implements Pipe { + * supports(obj) { + * return true; + * } + * + * onDestroy() {} + * + * transform(value, args = []) { + * return `${value}${value}`; + * } + * } + * ``` + */ + interface Pipe { + + supports(obj: any): boolean; + + onDestroy(): void; + + transform(value: any, args: List): any; + } + + interface PipeFactory { + + supports(obs: any): boolean; + + create(cdRef: ChangeDetectorRef): Pipe; + } + + class NullPipe extends BasePipe { + + called: boolean; + + supports(obj: any): boolean; + + transform(value: any, args?: List): WrappedValue; + } + + class NullPipeFactory implements PipeFactory { + + supports(obj: any): boolean; + + create(cdRef: ChangeDetectorRef): Pipe; + } + + var defaultPipes : Pipes ; + + + /** + * Provides default implementation of supports and onDestroy. + * + * #Example + * + * ``` + * class DoublePipe extends BasePipe {* + * transform(value) { + * return `${value}${value}`; + * } + * } + * ``` + */ + class BasePipe implements Pipe { + + supports(obj: any): boolean; + + onDestroy(): void; + + transform(value: any, args: List): any; + } + + class Locals { + + parent: Locals; + + current: Map; + + contains(name: string): boolean; + + get(name: string): any; + + set(name: string, value: any): void; + + clearValues(): void; + } + + + interface AbstractControl_onlySelfArgs { + onlySelf?: boolean; + } + + interface AbstractControl_updateValueAndValidityArgs { + onlySelf?: boolean; + emitEvent?: boolean; + } + + /** + * Omitting from external API doc as this is really an abstract internal concept. + */ + class AbstractControl { + + validator: Function; + + value: any; + + status: string; + + valid: boolean; + + errors: StringMap; + + pristine: boolean; + + dirty: boolean; + + touched: boolean; + + untouched: boolean; + + valueChanges: Observable; + + markAsTouched(): void; + + markAsDirty(args?:AbstractControl_onlySelfArgs): void; + + setParent(parent: any): void; + + updateValidity(args?:AbstractControl_onlySelfArgs): void; + + updateValueAndValidity(args?:AbstractControl_updateValueAndValidityArgs): void; + + find(path: List| string): AbstractControl; + + getError(errorCode: string, path?: List): any; + + hasError(errorCode: string, path?: List): boolean; + } + + class AbstractControlDirective { + + control: AbstractControl; + + value: any; + + valid: boolean; + + errors: StringMap; + + pristine: boolean; + + dirty: boolean; + + touched: boolean; + + untouched: boolean; + } + + + interface Control_updateValueOptions { + onlySelf?: boolean; + emitEvent?: boolean; + } + /** + * Defines a part of a form that cannot be divided into other controls. + * + * `Control` is one of the three fundamental building blocks used to define forms in Angular, along + * with + * {@link ControlGroup} and {@link ControlArray}. + */ + class Control extends AbstractControl { + + updateValue(value: any, options?: Control_updateValueOptions): void; + + registerOnChange(fn: Function): void; + } + + + /** + * Defines a part of a form, of fixed length, that can contain other controls. + * + * A ControlGroup aggregates the values and errors of each {@link Control} in the group. Thus, if + * one of the controls + * in a group is invalid, the entire group is invalid. Similarly, if a control changes its value, + * the entire group + * changes as well. + * + * `ControlGroup` is one of the three fundamental building blocks used to define forms in Angular, + * along with + * {@link Control} and {@link ControlArray}. {@link ControlArray} can also contain other controls, + * but is of variable + * length. + */ + class ControlGroup extends AbstractControl { + + controls: StringMap; + + addControl(name: string, c: AbstractControl): void; + + removeControl(name: string): void; + + include(controlName: string): void; + + exclude(controlName: string): void; + + contains(controlName: string): boolean; + } + + + /** + * Defines a part of a form, of variable length, that can contain other controls. + * + * A `ControlArray` aggregates the values and errors of each {@link Control} in the group. Thus, if + * one of the controls + * in a group is invalid, the entire group is invalid. Similarly, if a control changes its value, + * the entire group + * changes as well. + * + * `ControlArray` is one of the three fundamental building blocks used to define forms in Angular, + * along with {@link Control} and {@link ControlGroup}. {@link ControlGroup} can also contain + * other controls, but is of fixed length. + */ + class ControlArray extends AbstractControl { + + controls: List; + + at(index: number): AbstractControl; + + push(control: AbstractControl): void; + + insert(index: number, control: AbstractControl): void; + + removeAt(index: number): void; + + length: number; + } + + + /** + * Creates and binds a control with a specified name to a DOM element. + * + * This directive can only be used as a child of {@link NgForm} or {@link NgFormModel}. + * + * # Example + * + * In this example, we create the login and password controls. + * We can work with each control separately: check its validity, get its value, listen to its + * changes. + * + * ``` + * @Component({selector: "login-comp"}) + * @View({ + * directives: [formDirectives], + * template: ` + *
+ * Login + *
Login is invalid
+ * + * Password + * + * + *
+ * `}) + * class LoginComp { + * onLogIn(value) { + * // value === {login: 'some login', password: 'some password'} + * } + * } + * ``` + * + * We can also use ng-model to bind a domain model to the form. + * + * ``` + * @Component({selector: "login-comp"}) + * @View({ + * directives: [formDirectives], + * template: ` + *
+ * Login + * Password + * + *
+ * `}) + * class LoginComp { + * credentials: {login:string, password:string}; + * + * onLogIn() { + * // this.credentials.login === "some login" + * // this.credentials.password === "some password" + * } + * } + * ``` + */ + class NgControlName extends NgControl { + + update: void; + + model: any; + + ngValidators: QueryList; + + onChange(c: StringMap): void; + + onDestroy(): void; + + viewToModelUpdate(newValue: any): void; + + path: List; + + formDirective: any; + + control: Control; + + validator: Function; + } + + + /** + * Binds an existing control to a DOM element. + * + * # Example + * + * In this example, we bind the control to an input element. When the value of the input element + * changes, the value of + * the control will reflect that change. Likewise, if the value of the control changes, the input + * element reflects that + * change. + * + * ``` + * @Component({selector: "login-comp"}) + * @View({ + * directives: [formDirectives], + * template: "" + * }) + * class LoginComp { + * loginControl:Control; + * + * constructor() { + * this.loginControl = new Control(''); + * } + * } + * + * ``` + * + * We can also use ng-model to bind a domain model to the form. + * + * ``` + * @Component({selector: "login-comp"}) + * @View({ + * directives: [formDirectives], + * template: "" + * }) + * class LoginComp { + * loginControl:Control; + * login:string; + * + * constructor() { + * this.loginControl = new Control(''); + * } + * } + * ``` + */ + class NgFormControl extends NgControl { + + form: Control; + + update: void; + + model: any; + + ngValidators: QueryList; + + onChange(c: any): void; + + path: List; + + control: Control; + + validator: Function; + + viewToModelUpdate(newValue: any): void; + } + + + /** + * Binds a domain model to the form. + * + * # Example + * ``` + * @Component({selector: "search-comp"}) + * @View({ + * directives: [formDirectives], + * template: ` + * + * `}) + * class SearchComp { + * searchQuery: string; + * } + * ``` + */ + class NgModel extends NgControl { + + update: void; + + model: any; + + ngValidators: QueryList; + + onChange(c: any): void; + + control: Control; + + path: List; + + validator: Function; + + viewToModelUpdate(newValue: any): void; + } + + + /** + * An abstract class that all control directive extend. + * + * It binds a {@link Control} object to a DOM element. + */ + class NgControl extends AbstractControlDirective { + + name: string; + + valueAccessor: ControlValueAccessor; + + validator: Function; + + path: List; + + viewToModelUpdate(newValue: any): void; + } + + + /** + * Creates and binds a control group to a DOM element. + * + * This directive can only be used as a child of {@link NgForm} or {@link NgFormModel}. + * + * # Example + * + * In this example, we create the credentials and personal control groups. + * We can work with each group separately: check its validity, get its value, listen to its changes. + * + * ``` + * @Component({selector: "signup-comp"}) + * @View({ + * directives: [formDirectives], + * template: ` + *
+ *
+ * Login + * Password + *
+ *
Credentials are invalid
+ * + *
+ * Name + *
+ * + *
+ * `}) + * class SignupComp { + * onSignUp(value) { + * // value === {personal: {name: 'some name'}, + * // credentials: {login: 'some login', password: 'some password'}} + * } + * } + * + * ``` + */ + class NgControlGroup extends ControlContainer { + + onInit(): void; + + onDestroy(): void; + + control: ControlGroup; + + path: List; + + formDirective: Form; + } + + + /** + * Binds an existing control group to a DOM element. + * + * # Example + * + * In this example, we bind the control group to the form element, and we bind the login and + * password controls to the + * login and password elements. + * + * ``` + * @Component({selector: "login-comp"}) + * @View({ + * directives: [formDirectives], + * template: "
" + + * "Login " + + * "Password " + + * "" + + * "
" + * }) + * class LoginComp { + * loginForm:ControlGroup; + * + * constructor() { + * this.loginForm = new ControlGroup({ + * login: new Control(""), + * password: new Control("") + * }); + * } + * + * onLogin() { + * // this.loginForm.value + * } + * } + * + * ``` + * + * We can also use ng-model to bind a domain model to the form. + * + * ``` + * @Component({selector: "login-comp"}) + * @View({ + * directives: [formDirectives], + * template: "
" + + * "Login " + + * "Password " + + * "" + + * "
" + * }) + * class LoginComp { + * credentials:{login:string, password:string} + * loginForm:ControlGroup; + * + * constructor() { + * this.loginForm = new ControlGroup({ + * login: new Control(""), + * password: new Control("") + * }); + * } + * + * onLogin() { + * // this.credentials.login === 'some login' + * // this.credentials.password === 'some password' + * } + * } + * ``` + */ + class NgFormModel extends ControlContainer implements Form { + + form: ControlGroup; + + directives: List; + + ngSubmit: void; + + onChange(_: any): void; + + formDirective: Form; + + control: ControlGroup; + + path: List; + + addControl(dir: NgControl): void; + + getControl(dir: NgControl): Control; + + removeControl(dir: NgControl): void; + + addControlGroup(dir: NgControlGroup): void; + + removeControlGroup(dir: NgControlGroup): void; + + getControlGroup(dir: NgControlGroup): ControlGroup; + + updateModel(dir: NgControl, value: any): void; + + onSubmit(): boolean; + } + + + /** + * Creates and binds a form object to a DOM element. + * + * # Example + * + * ``` + * @Component({selector: "signup-comp"}) + * @View({ + * directives: [formDirectives], + * template: ` + *
+ *
+ * Login + * Password + *
+ *
Credentials are invalid
+ * + *
+ * Name + *
+ * + *
+ * `}) + * class SignupComp { + * onSignUp(value) { + * // value === {personal: {name: 'some name'}, + * // credentials: {login: 'some login', password: 'some password'}} + * } + * } + * + * ``` + */ + class NgForm extends ControlContainer implements Form { + + form: ControlGroup; + + ngSubmit: void; + + formDirective: Form; + + control: ControlGroup; + + path: List; + + controls: StringMap; + + addControl(dir: NgControl): void; + + getControl(dir: NgControl): Control; + + removeControl(dir: NgControl): void; + + addControlGroup(dir: NgControlGroup): void; + + removeControlGroup(dir: NgControlGroup): void; + + getControlGroup(dir: NgControlGroup): ControlGroup; + + updateModel(dir: NgControl, value: any): void; + + onSubmit(): boolean; + } + + + /** + * A bridge between a control and a native element. + * + * Please see {@link DefaultValueAccessor} for more information. + */ + interface ControlValueAccessor { + + writeValue(obj: any): void; + + registerOnChange(fn: any): void; + + registerOnTouched(fn: any): void; + } + + + /** + * The default accessor for writing a value and listening to changes that is used by the + * {@link NgModel}, {@link NgFormControl}, and {@link NgControlName} directives. + * + * # Example + * ``` + * + * ``` + */ + class DefaultValueAccessor implements ControlValueAccessor { + + value: string; + + onChange: void; + + onTouched: void; + + cd: NgControl; + + renderer: Renderer; + + elementRef: ElementRef; + + writeValue(value: any): void; + + ngClassUntouched: boolean; + + ngClassTouched: boolean; + + ngClassPristine: boolean; + + ngClassDirty: boolean; + + ngClassValid: boolean; + + ngClassInvalid: boolean; + + registerOnChange(fn: any): void; + + registerOnTouched(fn: any): void; + } + + + /** + * The accessor for writing a value and listening to changes on a checkbox input element. + * + * # Example + * ``` + * + * ``` + */ + class CheckboxControlValueAccessor implements ControlValueAccessor { + + checked: boolean; + + onChange: void; + + onTouched: void; + + cd: NgControl; + + renderer: Renderer; + + elementRef: ElementRef; + + writeValue(value: any): void; + + ngClassUntouched: boolean; + + ngClassTouched: boolean; + + ngClassPristine: boolean; + + ngClassDirty: boolean; + + ngClassValid: boolean; + + ngClassInvalid: boolean; + + registerOnChange(fn: any): void; + + registerOnTouched(fn: any): void; + } + + + /** + * The accessor for writing a value and listening to changes on a select element. + */ + class SelectControlValueAccessor implements ControlValueAccessor { + + value: void; + + onChange: void; + + onTouched: void; + + cd: NgControl; + + renderer: Renderer; + + elementRef: ElementRef; + + writeValue(value: any): void; + + ngClassUntouched: boolean; + + ngClassTouched: boolean; + + ngClassPristine: boolean; + + ngClassDirty: boolean; + + ngClassValid: boolean; + + ngClassInvalid: boolean; + + registerOnChange(fn: any): void; + + registerOnTouched(fn: any): void; + } + + + /** + * A list of all the form directives used as part of a `@View` annotation. + * + * This is a shorthand for importing them each individually. + */ + var formDirectives : List ; + + + /** + * Provides a set of validators used by form controls. + * + * # Example + * + * ``` + * var loginControl = new Control("", Validators.required) + * ``` + */ + class Validators { + } + + class NgValidator { + + validator: Function; + } + + class NgRequiredValidator extends NgValidator { + + validator: Function; + } + + + /** + * Creates a form object from a user-specified configuration. + * + * # Example + * + * ``` + * import {Component, View, bootstrap} from 'angular2/angular2'; + * import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms'; + * + * @Component({ + * selector: 'login-comp', + * viewInjector: [ + * FormBuilder + * ] + * }) + * @View({ + * template: ` + *
+ * Login + * + *
+ * Password + * Confirm password + *
+ *
+ * `, + * directives: [ + * formDirectives + * ] + * }) + * class LoginComp { + * loginForm: ControlGroup; + * + * constructor(builder: FormBuilder) { + * this.loginForm = builder.group({ + * login: ["", Validators.required], + * + * passwordRetry: builder.group({ + * password: ["", Validators.required], + * passwordConfirmation: ["", Validators.required] + * }) + * }); + * } + * } + * + * bootstrap(LoginComp) + * ``` + * + * This example creates a {@link ControlGroup} that consists of a `login` {@link Control}, and a + * nested + * {@link ControlGroup} that defines a `password` and a `passwordConfirmation` {@link Control}: + * + * ``` + * var loginForm = builder.group({ + * login: ["", Validators.required], + * + * passwordRetry: builder.group({ + * password: ["", Validators.required], + * passwordConfirmation: ["", Validators.required] + * }) + * }); + * + * ``` + */ + class FormBuilder { + + group(controlsConfig: StringMap, extra?: StringMap): ControlGroup; + + control(value: Object, validator?: Function): Control; + + array(controlsConfig: List, validator?: Function): ControlArray; + } + + var formInjectables : List ; + + + /** + * A dispatcher for all events happening in a view. + */ + interface EventDispatcher { + + + /** + * Called when an event was triggered for a on-* attribute on an element. + * @param {Map} locals Locals to be used to evaluate the + * event expressions + */ + dispatchEvent(elementIndex: number, eventName: string, locals: Map): void; + } + + class Renderer { + + + /** + * Creates a root host view that includes the given element. + * @param {RenderProtoViewRef} hostProtoViewRef a RenderProtoViewRef of type + * ProtoViewDto.HOST_VIEW_TYPE + * @param {any} hostElementSelector css selector for the host element (will be queried against the + * main document) + * @return {RenderViewRef} the created view + */ + createRootHostView(hostProtoViewRef: RenderProtoViewRef, hostElementSelector: string): RenderViewRef; + + + /** + * Creates a regular view out of the given ProtoView + */ + createView(protoViewRef: RenderProtoViewRef): RenderViewRef; + + + /** + * Destroys the given view after it has been dehydrated and detached + */ + destroyView(viewRef: RenderViewRef): void; + + + /** + * Attaches a componentView into the given hostView at the given element + */ + attachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef): void; + + + /** + * Detaches a componentView into the given hostView at the given element + */ + detachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef): void; + + + /** + * Attaches a view into a ViewContainer (in the given parentView at the given element) at the + * given index. + */ + attachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef): void; + + + /** + * Detaches a view into a ViewContainer (in the given parentView at the given element) at the + * given index. + */ + detachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef): void; + + + /** + * Hydrates a view after it has been attached. Hydration/dehydration is used for reusing views + * inside of the view pool. + */ + hydrateView(viewRef: RenderViewRef): void; + + + /** + * Dehydrates a view after it has been attached. Hydration/dehydration is used for reusing views + * inside of the view pool. + */ + dehydrateView(viewRef: RenderViewRef): void; + + + /** + * Returns the native element at the given location. + * Attention: In a WebWorker scenario, this should always return null! + */ + getNativeElementSync(location: RenderElementRef): any; + + + /** + * Sets a property on an element. + */ + setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any): void; + + + /** + * Sets an attribute on an element. + */ + setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string): void; + + + /** + * Sets a class on an element. + */ + setElementClass(location: RenderElementRef, className: string, isAdd: boolean): void; + + + /** + * Sets a style on an element. + */ + setElementStyle(location: RenderElementRef, styleName: string, styleValue: string): void; + + + /** + * Calls a method on an element. + */ + invokeElementMethod(location: RenderElementRef, methodName: string, args: List): void; + + + /** + * Sets the value of a text node. + */ + setText(viewRef: RenderViewRef, textNodeIndex: number, text: string): void; + + + /** + * Sets the dispatcher for all events of the given view + */ + setEventDispatcher(viewRef: RenderViewRef, dispatcher: EventDispatcher): void; + } + + + /** + * Abstract reference to the element which can be marshaled across web-worker boundry. + * + * This interface is used by the {@link Renderer} api. + */ + interface RenderElementRef { + + + /** + * Reference to the {@link RenderViewRef} where the `RenderElementRef` is inside of. + */ + renderView: RenderViewRef; + + + /** + * Index of the element inside the {@link ViewRef}. + * + * This is used internally by the Angular framework to locate elements. + */ + boundElementIndex: number; + } + + class RenderViewRef { + } + + class RenderProtoViewRef { + } + + class DomRenderer extends Renderer { + + createRootHostView(hostProtoViewRef: RenderProtoViewRef, hostElementSelector: string): RenderViewRef; + + createView(protoViewRef: RenderProtoViewRef): RenderViewRef; + + destroyView(view: RenderViewRef): void; + + getNativeElementSync(location: RenderElementRef): any; + + attachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef): void; + + setComponentViewRootNodes(componentViewRef: RenderViewRef, rootNodes: List): void; + + getRootNodes(viewRef: RenderViewRef): List; + + detachComponentView(location: RenderElementRef, componentViewRef: RenderViewRef): void; + + attachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef): void; + + detachViewInContainer(location: RenderElementRef, atIndex: number, viewRef: RenderViewRef): void; + + hydrateView(viewRef: RenderViewRef): void; + + dehydrateView(viewRef: RenderViewRef): void; + + setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any): void; + + setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string): void; + + setElementClass(location: RenderElementRef, className: string, isAdd: boolean): void; + + setElementStyle(location: RenderElementRef, styleName: string, styleValue: string): void; + + invokeElementMethod(location: RenderElementRef, methodName: string, args: List): void; + + setText(viewRef: RenderViewRef, textNodeIndex: number, text: string): void; + + setEventDispatcher(viewRef: RenderViewRef, dispatcher: any): void; + } + + var DOCUMENT_TOKEN:any; + + + /** + * Declare reusable UI building blocks for an application. + * + * Each Angular component requires a single `@Component` and at least one `@View` annotation. The + * `@Component` + * annotation specifies when a component is instantiated, and which properties and hostListeners it + * binds to. + * + * When a component is instantiated, Angular + * - creates a shadow DOM for the component. + * - loads the selected template into the shadow DOM. + * - creates all the injectable objects configured with `hostInjector` and `viewInjector`. + * + * All template expressions and statements are then evaluated against the component instance. + * + * For details on the `@View` annotation, see {@link View}. + * + * ## Example + * + * ``` + * @Component({ + * selector: 'greet' + * }) + * @View({ + * template: 'Hello {{name}}!' + * }) + * class Greet { + * name: string; + * + * constructor() { + * this.name = 'World'; + * } + * } + * ``` + */ + class ComponentAnnotation extends DirectiveAnnotation { + + + /** + * Defines the used change detection strategy. + * + * When a component is instantiated, Angular creates a change detector, which is responsible for + * propagating + * the component's bindings. + * + * The `changeDetection` property defines, whether the change detection will be checked every time + * or only when the component + * tells it to do so. + */ + changeDetection: string; + + + /** + * Defines the set of injectable objects that are visible to its view dom children. + * + * ## Simple Example + * + * Here is an example of a class that can be injected: + * + * ``` + * class Greeter { + * greet(name:string) { + * return 'Hello ' + name + '!'; + * } + * } + * + * @Directive({ + * selector: 'needs-greeter' + * }) + * class NeedsGreeter { + * greeter:Greeter; + * + * constructor(greeter:Greeter) { + * this.greeter = greeter; + * } + * } + * + * @Component({ + * selector: 'greet', + * viewInjector: [ + * Greeter + * ] + * }) + * @View({ + * template: ``, + * directives: [NeedsGreeter] + * }) + * class HelloWorld { + * } + * + * ``` + */ + viewInjector: List; + } + + + /** + * Directives allow you to attach behavior to elements in the DOM. + * + * {@link Directive}s with an embedded view are called {@link Component}s. + * + * A directive consists of a single directive annotation and a controller class. When the + * directive's `selector` matches + * elements in the DOM, the following steps occur: + * + * 1. For each directive, the `ElementInjector` attempts to resolve the directive's constructor + * arguments. + * 2. Angular instantiates directives for each matched element using `ElementInjector` in a + * depth-first order, + * as declared in the HTML. + * + * ## Understanding How Injection Works + * + * There are three stages of injection resolution. + * - *Pre-existing Injectors*: + * - The terminal {@link Injector} cannot resolve dependencies. It either throws an error or, if + * the dependency was + * specified as `@Optional`, returns `null`. + * - The platform injector resolves browser singleton resources, such as: cookies, title, + * location, and others. + * - *Component Injectors*: Each component instance has its own {@link Injector}, and they follow + * the same parent-child hierarchy + * as the component instances in the DOM. + * - *Element Injectors*: Each component instance has a Shadow DOM. Within the Shadow DOM each + * element has an `ElementInjector` + * which follow the same parent-child hierarchy as the DOM elements themselves. + * + * When a template is instantiated, it also must instantiate the corresponding directives in a + * depth-first order. The + * current `ElementInjector` resolves the constructor dependencies for each directive. + * + * Angular then resolves dependencies as follows, according to the order in which they appear in the + * {@link View}: + * + * 1. Dependencies on the current element + * 2. Dependencies on element injectors and their parents until it encounters a Shadow DOM boundary + * 3. Dependencies on component injectors and their parents until it encounters the root component + * 4. Dependencies on pre-existing injectors + * + * + * The `ElementInjector` can inject other directives, element-specific special objects, or it can + * delegate to the parent + * injector. + * + * 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 + * 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. + * - `@Parent() directive:DirectiveType`: any directive that matches the type on a direct parent + * element only. + * - `@Query(DirectiveType) query:QueryList`: A live collection of direct child + * directives. + * - `@QueryDescendants(DirectiveType) query:QueryList`: A live collection of any + * child directives. + * + * To inject element-specific special objects, declare the constructor parameter as: + * - `element: ElementRef` to obtain a reference to logical element in the view. + * - `viewContainer: ViewContainerRef` to control child template instantiation, for + * {@link Directive} directives only + * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way. + * + * ## Example + * + * The following example demonstrates how dependency injection resolves constructor arguments in + * practice. + * + * + * Assume this HTML template: + * + * ``` + *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ``` + * + * With the following `dependency` decorator and `SomeService` injectable class. + * + * ``` + * @Injectable() + * class SomeService { + * } + * + * @Directive({ + * selector: '[dependency]', + * properties: [ + * 'id: dependency' + * ] + * }) + * class Dependency { + * id:string; + * } + * ``` + * + * Let's step through the different ways in which `MyDirective` could be declared... + * + * + * ### No injection + * + * Here the constructor is declared with no arguments, therefore nothing is injected into + * `MyDirective`. + * + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor() { + * } + * } + * ``` + * + * This directive would be instantiated with no dependencies. + * + * + * ### Component-level injection + * + * Directives can inject any injectable instance from the closest component injector or any of its + * parents. + * + * Here, the constructor declares a parameter, `someService`, and injects the `SomeService` type + * from the parent + * component's injector. + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor(someService: SomeService) { + * } + * } + * ``` + * + * This directive would be instantiated with a dependency on `SomeService`. + * + * + * ### Injecting a directive from the current element + * + * Directives can inject other directives declared on the current element. + * + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor(dependency: Dependency) { + * expect(dependency.id).toEqual(3); + * } + * } + * ``` + * This directive would be instantiated with `Dependency` declared at the same element, in this case + * `dependency="3"`. + * + * + * ### Injecting a directive from a direct parent element + * + * Directives can inject other directives declared on a direct parent element. By definition, a + * directive with a + * `@Parent` annotation does not attempt to resolve dependencies for the current element, even if + * this would satisfy + * the dependency. + * + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor(@Parent() dependency: Dependency) { + * expect(dependency.id).toEqual(2); + * } + * } + * ``` + * This directive would be instantiated with `Dependency` declared at the parent element, in this + * case `dependency="2"`. + * + * + * ### 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. + * + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor(@Ancestor() dependency: Dependency) { + * expect(dependency.id).toEqual(2); + * } + * } + * ``` + * + * Unlike the `@Parent` which only checks the parent, `@Ancestor` checks 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"`. + * + * + * ### Injecting a live collection of direct child directives + * + * + * A directive can also query for other child directives. Since parent directives are instantiated + * before child directives, a directive can't simply inject the list of child directives. Instead, + * the directive injects a {@link QueryList}, which updates its contents as children are added, + * removed, or moved by a directive that uses a {@link ViewContainerRef} such as a `ng-for`, an + * `ng-if`, or an `ng-switch`. + * + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor(@Query(Dependency) dependencies:QueryList) { + * } + * } + * ``` + * + * This directive would be instantiated with a {@link QueryList} which contains `Dependency` 4 and + * 6. Here, `Dependency` 5 would not be included, because it is not a direct child. + * + * ### Injecting a live collection of descendant directives + * + * By passing the descendant flag to `@Query` above, we can include the children of the child + * elements. + * + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor(@Query(Dependency, {descendants: true}) dependencies:QueryList) { + * } + * } + * ``` + * + * This directive would be instantiated with a Query which would contain `Dependency` 4, 5 and 6. + * + * ### Optional injection + * + * The normal behavior of directives is to return an error when a specified dependency cannot be + * resolved. If you + * would like to inject `null` on unresolved dependency instead, you can annotate that dependency + * with `@Optional()`. + * This explicitly permits the author of a template to treat some of the surrounding directives as + * optional. + * + * ``` + * @Directive({ selector: '[my-directive]' }) + * class MyDirective { + * constructor(@Optional() dependency:Dependency) { + * } + * } + * ``` + * + * This directive would be instantiated with a `Dependency` directive found on the current element. + * If none can be + * found, the injector supplies `null` instead of throwing an error. + * + * ## Example + * + * Here we use a decorator directive to simply define basic tool-tip behavior. + * + * ``` + * @Directive({ + * selector: '[tooltip]', + * properties: [ + * 'text: tooltip' + * ], + * hostListeners: { + * 'onmouseenter': 'onMouseEnter()', + * 'onmouseleave': 'onMouseLeave()' + * } + * }) + * class Tooltip{ + * text:string; + * overlay:Overlay; // NOT YET IMPLEMENTED + * overlayManager:OverlayManager; // NOT YET IMPLEMENTED + * + * constructor(overlayManager:OverlayManager) { + * this.overlay = overlay; + * } + * + * onMouseEnter() { + * // exact signature to be determined + * this.overlay = this.overlayManager.open(text, ...); + * } + * + * onMouseLeave() { + * this.overlay.close(); + * this.overlay = null; + * } + * } + * ``` + * In our HTML template, we can then add this behavior to a `
` or any other element with the + * `tooltip` selector, + * like so: + * + * ``` + *
+ * ``` + * + * Directives can also control the instantiation, destruction, and positioning of inline template + * elements: + * + * A directive uses a {@link ViewContainerRef} to instantiate, insert, move, and destroy views at + * runtime. + * The {@link ViewContainerRef} is created as a result of `