`
* - Next parent has the `Dependency` directive and so the dependency is satisfied.
*
* Angular injects `dependency=2`.
*
* @exportedAs angular2/annotations
*/
class AncestorAnnotation extends Visibility {
}
/**
* Specifies that an injector should retrieve a dependency from the direct parent.
*
* ## Example
*
* Here is a simple directive that retrieves a dependency from its parent element.
*
* ```
* @Directive({
* selector: '[dependency]',
* properties: [
* 'id: dependency'
* ]
* })
* class Dependency {
* id:string;
* }
*
*
* @Directive({
* selector: '[my-directive]'
* })
* class Dependency {
* constructor(@Parent() dependency:Dependency) {
* expect(dependency.id).toEqual(1);
* };
* }
* ```
*
* We use this with the following HTML template:
*
* ```
*
* ```
* The `@Parent()` annotation in our constructor forces the injector to retrieve the dependency from
* the
* parent element (even thought the current element could resolve it): Angular injects
* `dependency=1`.
*
* @exportedAs angular2/annotations
*/
class ParentAnnotation extends Visibility {
}
/**
* Specifies that an injector should retrieve a dependency from any ancestor element.
*
* An ancestor is any element between the parent element and shadow root.
*
*
* ## Example
*
* Here is a simple directive that retrieves a dependency from an ancestor element.
*
* ```
* @Directive({
* selector: '[dependency]',
* properties: [
* 'id: dependency'
* ]
* })
* class Dependency {
* id:string;
* }
*
*
* @Directive({
* selector: '[my-directive]'
* })
* class Dependency {
* constructor(@Unbounded() dependency:Dependency) {
* expect(dependency.id).toEqual(2);
* };
* }
* ```
*
* @exportedAs angular2/annotations
*/
class UnboundedAnnotation extends Visibility {
}
/**
* Declares the available HTML templates for an application.
*
* Each angular component requires a single `@Component` and at least one `@View` annotation. The
* `@View` annotation specifies the HTML template to use, and lists the directives that are active
* within the template.
*
* When a component is instantiated, the template is loaded into the component's shadow root, and
* the expressions and statements in the template are evaluated against the component.
*
* For details on the `@Component` annotation, see {@link Component}.
*
* ## Example
*
* ```
* @Component({
* selector: 'greet'
* })
* @View({
* template: 'Hello {{name}}!',
* directives: [GreetUser, Bold]
* })
* class Greet {
* name: string;
*
* constructor() {
* this.name = 'World';
* }
* }
* ```
*/
function View(arg: _ViewArg): (target: any) => any;
interface _ViewArg {
/**
* Specifies a template URL for an angular component.
*
* NOTE: either `templateUrl` or `template` should be used, but not both.
*/
templateUrl?: string;
/**
* Specifies an inline template for an angular component.
*
* NOTE: either `templateUrl` or `template` should be used, but not both.
*/
template?: string;
/**
* Specifies a list of directives that can be used within a template.
*
* Directives must be listed explicitly to provide proper component encapsulation.
*
* ## Example
*
* ```javascript
* @Component({
* selector: 'my-component'
* })
* @View({
* directives: [For]
* template: '
*
'
* })
* class MyComponent {
* }
* ```
*/
// TODO(tbosch): use Type | Binding | List
when Dart supports union types,
// as otherwise we would need to import Binding type and Dart would warn
// for an unused import.
directives?: List>;
/**
* Specify a custom renderer for this View.
* If this is set, neither `template`, `templateURL` nor `directives` are used.
*/
renderer?: string;
}
class ViewAnnotation {
}
/**
* Bootstrapping for Angular applications.
*
* You instantiate an Angular application by explicitly specifying a component to use as the root
* component for your
* application via the `bootstrap()` method.
*
* ## Simple Example
*
* Assuming this `index.html`:
*
* ```html
*
*
*
* loading...
*
*
* ```
*
* An application is bootstrapped inside an existing browser DOM, typically `index.html`. Unlike
* Angular 1, Angular 2
* does not compile/process bindings in `index.html`. This is mainly for security reasons, as well
* as architectural
* changes in Angular 2. This means that `index.html` can safely be processed using server-side
* technologies such as
* bindings. Bindings can thus use double-curly `{{ syntax }}` without collision from Angular 2
* component double-curly
* `{{ syntax }}`.
*
* We can use this script code:
*
* ```
* @Component({
* selector: 'my-app'
* })
* @View({
* template: 'Hello {{ name }}!'
* })
* class MyApp {
* name:string;
*
* constructor() {
* this.name = 'World';
* }
* }
*
* main() {
* return bootstrap(MyApp);
* }
* ```
*
* When the app developer invokes `bootstrap()` with the root component `MyApp` as its argument,
* Angular performs the
* following tasks:
*
* 1. It uses the component's `selector` property to locate the DOM element which needs to be
* upgraded into
* the angular component.
* 2. It creates a new child injector (from the platform injector) and configures the injector with
* the component's
* `appInjector`. Optionally, you can also override the injector configuration for an app by
* invoking
* `bootstrap` with the `componentInjectableBindings` argument.
* 3. It creates a new `Zone` and connects it to the angular application's change detection domain
* instance.
* 4. It creates a shadow DOM on the selected component's host element and loads the template into
* it.
* 5. It instantiates the specified component.
* 6. Finally, Angular performs change detection to apply the initial data bindings for the
* application.
*
*
* ## Instantiating Multiple Applications on a Single Page
*
* There are two ways to do this.
*
*
* ### Isolated Applications
*
* Angular creates a new application each time that the `bootstrap()` method is invoked. When
* multiple applications
* are created for a page, Angular treats each application as independent within an isolated change
* detection and
* `Zone` domain. If you need to share data between applications, use the strategy described in the
* next
* section, "Applications That Share Change Detection."
*
*
* ### Applications That Share Change Detection
*
* If you need to bootstrap multiple applications that share common data, the applications must
* share a common
* change detection and zone. To do that, create a meta-component that lists the application
* components in its template.
* By only invoking the `bootstrap()` method once, with the meta-component as its argument, you
* ensure that only a
* single change detection zone is created and therefore data can be shared across the applications.
*
*
* ## Platform Injector
*
* When working within a browser window, there are many singleton resources: cookies, title,
* location, and others.
* Angular services that represent these resources must likewise be shared across all Angular
* applications that
* occupy the same browser window. For this reason, Angular creates exactly one global platform
* injector which stores
* all shared services, and each angular application injector has the platform injector as its
* parent.
*
* Each application has its own private injector as well. When there are multiple applications on a
* page, Angular treats
* each application injector's services as private to that application.
*
*
* # API
* - `appComponentType`: The root component which should act as the application. This is a reference
* to a `Type`
* which is annotated with `@Component(...)`.
* - `componentInjectableBindings`: An additional set of bindings that can be added to `appInjector`
* for the
* Component
to override default injection behavior.
* - `errorReporter`: `function(exception:any, stackTrace:string)` a default error reporter for
* unhandled exceptions.
*
* Returns a `Promise` with the application`s private Injector
.
*
* @exportedAs angular2/core
*/
function bootstrap(appComponentType: Type, componentInjectableBindings?: List>, errorReporter?: Function) : Promise ;
class ApplicationRef {
dispose(): any;
hostComponent: any;
hostComponentType: any;
injector: any;
}
var appComponentRefToken : OpaqueToken ;
var appComponentTypeToken : OpaqueToken ;
/**
* Specifies that a QueryList should be injected.
*
* See QueryList for usage and example.
*
* @exportedAs angular2/annotations
*/
class QueryAnnotation extends DependencyAnnotation {
directive: any;
}
/**
* Specifies that a constant attribute value should be injected.
*
* The directive can inject constant string literals of host element attributes.
*
* ## Example
*
* Suppose we have an ` ` element and want to know its `type`.
*
* ```html
*
* ```
*
* A decorator can inject string literal `text` like so:
*
* ```javascript
* @Directive({
* selector: `input'
* })
* class InputDirective {
* constructor(@Attribute('type') type) {
* // type would be `text` in this example
* }
* }
* ```
*
* @exportedAs angular2/annotations
*/
class AttributeAnnotation extends DependencyAnnotation {
attributeName: string;
token: any;
}
/**
* Cache that stores the AppProtoView of the template of a component.
* Used to prevent duplicate work and resolve cyclic dependencies.
*/
class CompilerCache {
clear(): void;
get(component: Type): AppProtoView;
set(component: Type, protoView: AppProtoView): void;
}
/**
* @exportedAs angular2/view
*/
class Compiler {
compile(component: Type): Promise;
compileInHost(componentTypeOrBinding: Type | Binding): Promise;
}
/**
* Defines lifecycle method [onChange] called after all of component's bound
* properties are updated.
*/
interface OnChange {
onChange(changes: StringMap): void;
}
/**
* Defines lifecycle method [onDestroy] called when a directive is being destroyed.
*/
interface OnDestroy {
onDestroy(): void;
}
/**
* Defines lifecycle method [onCheck] called when a directive is being checked.
*/
interface OnCheck {
onCheck(): void;
}
/**
* Defines lifecycle method [onInit] called when a directive is being checked the first time.
*/
interface OnInit {
onInit(): void;
}
/**
* Defines lifecycle method [onAllChangesDone ] called when the bindings of all its children have
* been changed.
*/
interface OnAllChangesDone {
onAllChangesDone(): void;
}
/**
* An iterable live list of components in the Light DOM.
*
* Injectable Objects that contains a live list of child directives in the light DOM of a directive.
* The directives are kept in depth-first pre-order traversal of the DOM.
*
* The `QueryList` is iterable, therefore it can be used in both javascript code with `for..of` loop
* as well as in
* template with `*ng-for="of"` directive.
*
* NOTE: In the future this class will implement an `Observable` interface. For now it uses a plain
* list of observable
* callbacks.
*
* # Example:
*
* Assume that `` component would like to get a list its children which are ``
* components as shown in this
* example:
*
* ```html
*
* ...
* {{o.text}}
*
* ```
*
* In the above example the list of `` elements needs to get a list of `` elements so
* that it could render
* tabs with the correct titles and in the correct order.
*
* A possible solution would be for a `` to inject `` component and then register itself
* with ``
* component's on `hydrate` and deregister on `dehydrate` event. While a reasonable approach, this
* would only work
* partialy since `*ng-for` could rearange the list of `` components which would not be
* reported to ``
* component and thus the list of `` componets would be out of sync with respect to the list
* of `` elements.
*
* A preferred solution is to inject a `QueryList` which is a live list of directives in the
* component`s light DOM.
*
* ```javascript
* @Component({
* selector: 'tabs'
* })
* @View({
* template: `
*
*
* `
* })
* class Tabs {
* panes: QueryList
*
* constructor(@Query(Pane) panes:QueryList) {
* this.panes = panes;
* }
* }
*
* @Component({
* selector: 'pane',
* properties: ['title']
* })
* @View(...)
* class Pane {
* title:string;
* }
* ```
*
* @exportedAs angular2/view
*/
class QueryList extends BaseQueryList {
onChange(callback: any): any;
removeCallback(callback: any): any;
}
class DirectiveResolver {
resolve(type: Type): DirectiveAnnotation;
}
/**
* @exportedAs angular2/view
*/
class ComponentRef {
dispose: Function;
hostView: ViewRef;
instance: any;
location: ElementRef;
}
/**
* Service for dynamically loading a Component into an arbitrary position in the internal Angular
* application tree.
*
* @exportedAs angular2/view
*/
class DynamicComponentLoader {
/**
* Loads a root component that is placed at the first element that matches the
* component's selector.
* The loaded component receives injection normally as a hosted view.
*/
loadAsRoot(typeOrBinding: any, overrideSelector?: any, injector?: Injector): Promise;
/**
* Loads a component into the location given by the provided ElementRef. The loaded component
* receives injection as if it in the place of the provided ElementRef.
*/
loadIntoExistingLocation(typeOrBinding: any, location: ElementRef, injector?: Injector): Promise;
/**
* Loads a component into a free host view that is not yet attached to
* a parent on the render side, although it is attached to a parent in the injector hierarchy.
* The loaded component receives injection normally as a hosted view.
*/
loadIntoNewLocation(typeOrBinding: any, parentComponentLocation: ElementRef, injector?: Injector): Promise;
/**
* Loads a component next to the provided ElementRef. The loaded component receives
* injection normally as a hosted view.
*/
loadNextToExistingLocation(typeOrBinding: any, location: ElementRef, injector?: Injector): Promise;
}
/**
* 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 a child {@link Injector} which is configured with the `appInjector` for the
* {@link Component}.
*
* 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';
* }
* }
* ```
*
*
* Dynamically loading a component at runtime:
*
* Regular Angular components are statically resolved. Dynamic components allows to resolve a
* component at runtime
* instead by providing a placeholder into which a regular Angular component can be dynamically
* loaded. Once loaded,
* the dynamically-loaded component becomes permanent and cannot be changed.
* Dynamic components are declared just like components, but without a `@View` annotation.
*
*
* ## Example
*
* Here we have `DynamicComp` which acts as the placeholder for `HelloCmp`. At runtime, the dynamic
* component
* `DynamicComp` requests loading of the `HelloCmp` component.
*
* There is nothing special about `HelloCmp`, which is a regular Angular component. It can also be
* used in other static
* locations.
*
* ```
* @Component({
* selector: 'dynamic-comp'
* })
* class DynamicComp {
* helloCmp:HelloCmp;
* constructor(loader:DynamicComponentLoader, location:ElementRef) {
* loader.load(HelloCmp, location).then((helloCmp) => {
* this.helloCmp = helloCmp;
* });
* }
* }
*
* @Component({
* selector: 'hello-cmp'
* })
* @View({
* template: "{{greeting}}"
* })
* class HelloCmp {
* greeting:string;
* constructor() {
* this.greeting = "hello";
* }
* }
* ```
*/
function Component(arg: _ComponentArg): (target: any) => any;
interface _ComponentArg {
/**
* 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 a Component and its children.
*
* The `appInjector` defined in the Component annotation allow you to configure a set of bindings
* for the component's
* injector.
*
* When a component is instantiated, Angular creates a new child Injector, which is configured
* with the bindings in
* the Component `appInjector` annotation. The injectable objects then become available for
* injection to the component
* itself and any of the directives in the component's template, i.e. they are not available to
* the directives which
* are children in the component's light DOM.
*
*
* The syntax for configuring the `appInjector` injectable is identical to {@link Injector}
* injectable configuration.
* See {@link Injector} for additional detail.
*
*
* ## Simple Example
*
* Here is an example of a class that can be injected:
*
* ```
* class Greeter {
* greet(name:string) {
* return 'Hello ' + name + '!';
* }
* }
*
* @Component({
* selector: 'greet',
* appInjector: [
* Greeter
* ]
* })
* @View({
* template: `{{greeter.greet('world')}}!`,
* directives: [Child]
* })
* class HelloWorld {
* greeter:Greeter;
*
* constructor(greeter:Greeter) {
* this.greeter = greeter;
* }
* }
* ```
*/
appInjector?: List;
/**
* 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;
selector?: string;
properties?: List;
events?: List;
hostListeners?: StringMap;
hostProperties?: StringMap;
hostAttributes?: StringMap;
hostActions?: StringMap;
exportAs?: string;
lifecycle?: List;
hostInjector?: List;
compileChildren?: boolean;
}
class ComponentAnnotation extends DirectiveAnnotation {
}
/**
* Directives allow you to attach behavior to elements in the DOM.
*
* Directive
s with an embedded view are called 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 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 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
* 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
* 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 QueryList , which updates its contents as children are added,
* removed, or moved by a directive that uses a 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 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
*
* Note: This is will be implemented in later release. ()
*
* Similar to `@Query` above, but also includes the children of the child elements.
*
* ```
* @Directive({ selector: '[my-directive]' })
* class MyDirective {
* constructor(@QueryDescendents(Dependency) 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
ViewContainerRef
to instantiate, insert, move, and destroy views at
* runtime.
* The
ViewContainerRef
is created as a result of `
` element, and represents a
* location in the current view
* where these actions are performed.
*
* Views are always created as children of the current View
, and as siblings of the
* `` element. Thus a
* directive in a child view cannot inject the directive that created it.
*
* Since directives that create views via ViewContainers are common in Angular, and using the full
* `` element syntax is wordy, Angular
* also supports a shorthand notation: `` and ` ` are
* equivalent.
*
* Thus,
*
* ```
*
* ```
*
* Expands in use to:
*
* ```
*
* ```
*
* Notice that although the shorthand places `*foo="bar"` within the ` ` element, the binding for
* the directive
* controller is correctly instantiated on the `` element rather than the `` element.
*
*
* ## Example
*
* Let's suppose we want to implement the `unless` behavior, to conditionally include a template.
*
* Here is a simple directive that triggers on an `unless` selector:
*
* ```
* @Directive({
* selector: '[unless]',
* properties: ['unless']
* })
* export class Unless {
* viewContainer: ViewContainerRef;
* protoViewRef: ProtoViewRef;
* prevCondition: boolean;
*
* constructor(viewContainer: ViewContainerRef, protoViewRef: ProtoViewRef) {
* this.viewContainer = viewContainer;
* this.protoViewRef = protoViewRef;
* this.prevCondition = null;
* }
*
* set unless(newCondition) {
* if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
* this.prevCondition = true;
* this.viewContainer.clear();
* } else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
* this.prevCondition = false;
* this.viewContainer.create(this.protoViewRef);
* }
* }
* }
* ```
*
* We can then use this `unless` selector in a template:
* ```
*
* ```
*
* Once the directive instantiates the child view, the shorthand notation for the template expands
* and the result is:
*
* ```
*
* ```
*
* Note also that although the ` ` template still exists inside the ` `,
* the instantiated
* view occurs on the second ` ` which is a sibling to the `` element.
*
* @exportedAs angular2/annotations
*/
function Directive(arg: _DirectiveArg): (target: any) => any;
interface _DirectiveArg {
/**
* If set to true the compiler does not compile the children of this directive.
*/
compileChildren?: boolean;
/**
* Enumerates the set of emitted events.
*
* ## Syntax
*
* ```
* @Component({
* events: ['statusChange']
* })
* class TaskComponent {
* statusChange:EventEmitter;
*
* constructor() {
* this.statusChange = new EventEmitter();
* }
*
* onComplete() {
* this.statusChange.next('completed');
* }
* }
* ```
*/
events?: List;
/**
* Specifies which DOM methods a directive can invoke.
*
* ## Syntax
*
* ```
* @Directive({
* selector: 'input',
* hostActions: {
* 'emitFocus': 'focus()'
* }
* })
* class InputDirective {
* constructor() {
* this.emitFocus = new EventEmitter();
* }
*
* focus() {
* this.emitFocus.next();
* }
* }
*
* In this example calling focus on InputDirective will result in calling focus on the DOM
* element.
* ```
*/
hostActions?: StringMap;
/**
* Specifies static attributes that should be propagated to a host element. Attributes specified
* in `hostAttributes`
* are propagated only if a given attribute is not present on a host element.
*
* ## Syntax
*
* ```
* @Directive({
* selector: '[my-button]',
* hostAttributes: {
* 'role': 'button'
* }
* })
* class MyButton {
* }
*
* In this example using `my-button` directive (ex.: `
`) on a host element
* (here: `` )
* will ensure that this element will get the "button" role.
* ```
*/
hostAttributes?: StringMap
;
/**
* Defines the set of injectable objects that are visible to a Directive and its light 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: 'greet',
* hostInjector: [
* Greeter
* ]
* })
* class HelloWorld {
* greeter:Greeter;
*
* constructor(greeter:Greeter) {
* this.greeter = greeter;
* }
* }
* ```
*/
hostInjector?: List;
/**
* Specifies which DOM hostListeners a directive listens to.
*
* The `hostListeners` property defines a set of `event` to `method` key-value pairs:
*
* - `event1`: the DOM event that the directive listens to.
* - `statement`: the statement to execute when the event occurs.
* If the evalutation of the statement returns `false`, then `preventDefault`is applied on the DOM
* event.
*
* To listen to global events, a target must be added to the event name.
* The target can be `window`, `document` or `body`.
*
* When writing a directive event binding, you can also refer to the following local variables:
* - `$event`: Current event object which triggered the event.
* - `$target`: The source of the event. This will be either a DOM element or an Angular
* directive.
* (will be implemented in later release)
*
*
* ## Syntax
*
* ```
* @Directive({
* hostListeners: {
* 'event1': 'onMethod1(arguments)',
* 'target:event2': 'onMethod2(arguments)',
* ...
* }
* }
* ```
*
* ## Basic Event Binding:
*
* Suppose you want to write a directive that triggers on `change` events in the DOM and on
* `resize` events in window.
* You would define the event binding as follows:
*
* ```
* @Directive({
* selector: 'input',
* hostListeners: {
* 'change': 'onChange($event)',
* 'window:resize': 'onResize($event)'
* }
* })
* class InputDirective {
* onChange(event:Event) {
* }
* onResize(event:Event) {
* }
* }
* ```
*
* Here the `onChange` method of `InputDirective` is invoked whenever the DOM element fires the
* 'change' event.
*/
hostListeners?: StringMap;
/**
* Specifies which DOM properties a directives updates.
*
* ## Syntax
*
* ```
* @Directive({
* selector: 'input',
* hostProperties: {
* 'value': 'value'
* }
* })
* class InputDirective {
* value:string;
* }
*
* In this example every time the value property of the decorator changes, Angular will update the
* value property of
* the host element.
* ```
*/
hostProperties?: StringMap;
/**
* Specifies a set of lifecycle hostListeners in which the directive participates.
*
* See onChange , onDestroy ,
* onAllChangesDone for details.
*/
lifecycle?: List;
/**
* Enumerates the set of properties that accept data binding for a directive.
*
* The `properties` property defines a set of `directiveProperty` to `bindingProperty`
* configuration:
*
* - `directiveProperty` specifies the component property where the value is written.
* - `bindingProperty` specifies the DOM property where the value is read from.
*
* You can include a Pipe
when specifying a `bindingProperty` to allow for data
* transformation and structural change detection of the value. These pipes will be evaluated in
* the context of this component.
*
* ## Syntax
*
* There is no need to specify both `directiveProperty` and `bindingProperty` when they both have
* the same value.
*
* ```
* @Directive({
* properties: [
* 'propertyName', // shorthand notation for 'propertyName: propertyName'
* 'directiveProperty1: bindingProperty1',
* 'directiveProperty2: bindingProperty2 | pipe1 | ...',
* ...
* ]
* }
* ```
*
*
* ## Basic Property Binding
*
* We can easily build a simple `Tooltip` directive that exposes a `tooltip` property, which can
* be used in templates with standard Angular syntax. For example:
*
* ```
* @Directive({
* selector: '[tooltip]',
* properties: [
* 'text: tooltip'
* ]
* })
* class Tooltip {
* set text(value: string) {
* // This will get called every time with the new value when the 'tooltip' property changes
* }
* }
* ```
*
* We can then bind to the `tooltip' property as either an expression (`someExpression`) or as a
* string literal, as shown in the HTML template below:
*
* ```html
* ...
* ...
* ```
*
* Whenever the `someExpression` expression changes, the `properties` declaration instructs
* Angular to update the `Tooltip`'s `text` property.
*
* ## Bindings With Pipes
*
* You can also use pipes when writing binding definitions for a directive.
*
* For example, we could write a binding that updates the directive on structural changes, rather
* than on reference changes, as normally occurs in change detection.
*
* See Pipe
and keyValDiff documentation for more details.
*
* ```
* @Directive({
* selector: '[class-set]',
* properties: [
* 'classChanges: classSet | keyValDiff'
* ]
* })
* class ClassSet {
* set classChanges(changes: KeyValueChanges) {
* // This will get called every time the `class-set` expressions changes its structure.
* }
* }
* ```
*
* The template that this directive is used in may also contain its own pipes. For example:
*
* ```html
*
* ```
*
* In this case, the two pipes compose as if they were inlined: `someExpression | somePipe |
* keyValDiff`.
*/
properties?: List
;
/**
* The CSS selector that triggers the instantiation of a directive.
*
* Angular only allows directives to trigger on CSS selectors that do not cross element
* boundaries.
*
* `selector` may be declared as one of the following:
*
* - `element-name`: select by element name.
* - `.class`: select by class name.
* - `[attribute]`: select by attribute name.
* - `[attribute=value]`: select by attribute name and value.
* - `:not(sub_selector)`: select only if the element does not match the `sub_selector`.
* - `selector1, selector2`: select if either `selector1` or `selector2` matches.
*
*
* ## Example
*
* Suppose we have a directive with an `input[type=text]` selector.
*
* And the following HTML:
*
* ```html
*