repackaging: all the file moves
This commit is contained in:
456
modules/@angular/core/src/metadata/di.ts
Normal file
456
modules/@angular/core/src/metadata/di.ts
Normal file
@ -0,0 +1,456 @@
|
||||
import {Type, stringify, isPresent, isString} from 'angular2/src/facade/lang';
|
||||
import {resolveForwardRef} from 'angular2/src/core/di';
|
||||
import {DependencyMetadata} from 'angular2/src/core/di/metadata';
|
||||
|
||||
/**
|
||||
* 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 `<input>` element and want to know its `type`.
|
||||
*
|
||||
* ```html
|
||||
* <input type="text">
|
||||
* ```
|
||||
*
|
||||
* A decorator can inject string literal `text` like so:
|
||||
*
|
||||
* {@example core/ts/metadata/metadata.ts region='attributeMetadata'}
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class AttributeMetadata extends DependencyMetadata {
|
||||
constructor(public attributeName: string) { super(); }
|
||||
|
||||
get token(): AttributeMetadata {
|
||||
// Normally one would default a token to a type of an injected value but here
|
||||
// the type of a variable is "string" and we can't use primitive type as a return value
|
||||
// so we use instance of Attribute instead. This doesn't matter much in practice as arguments
|
||||
// with @Attribute annotation are injected by ElementInjector that doesn't take tokens into
|
||||
// account.
|
||||
return this;
|
||||
}
|
||||
toString(): string { return `@Attribute(${stringify(this.attributeName)})`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares an injectable parameter to be a live list of directives or variable
|
||||
* bindings from the content children of a directive.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
|
||||
*
|
||||
* Assume that `<tabs>` component would like to get a list its children `<pane>`
|
||||
* components as shown in this example:
|
||||
*
|
||||
* ```html
|
||||
* <tabs>
|
||||
* <pane title="Overview">...</pane>
|
||||
* <pane *ngFor="let o of objects" [title]="o.title">{{o.text}}</pane>
|
||||
* </tabs>
|
||||
* ```
|
||||
*
|
||||
* The preferred solution is to query for `Pane` directives using this decorator.
|
||||
*
|
||||
* ```javascript
|
||||
* @Component({
|
||||
* selector: 'pane',
|
||||
* inputs: ['title']
|
||||
* })
|
||||
* class Pane {
|
||||
* title:string;
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'tabs',
|
||||
* template: `
|
||||
* <ul>
|
||||
* <li *ngFor="let pane of panes">{{pane.title}}</li>
|
||||
* </ul>
|
||||
* <ng-content></ng-content>
|
||||
* `
|
||||
* })
|
||||
* class Tabs {
|
||||
* panes: QueryList<Pane>;
|
||||
* constructor(@Query(Pane) panes:QueryList<Pane>) {
|
||||
* this.panes = panes;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* A query can look for variable bindings by passing in a string with desired binding symbol.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/sT2j25cH1dURAyBRCKx1?p=preview))
|
||||
* ```html
|
||||
* <seeker>
|
||||
* <div #findme>...</div>
|
||||
* </seeker>
|
||||
*
|
||||
* @Component({ selector: 'seeker' })
|
||||
* class Seeker {
|
||||
* constructor(@Query('findme') elList: QueryList<ElementRef>) {...}
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In this case the object that is injected depend on the type of the variable
|
||||
* binding. It can be an ElementRef, a directive or a component.
|
||||
*
|
||||
* Passing in a comma separated list of variable bindings will query for all of them.
|
||||
*
|
||||
* ```html
|
||||
* <seeker>
|
||||
* <div #find-me>...</div>
|
||||
* <div #find-me-too>...</div>
|
||||
* </seeker>
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'seeker'
|
||||
* })
|
||||
* class Seeker {
|
||||
* constructor(@Query('findMe, findMeToo') elList: QueryList<ElementRef>) {...}
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Configure whether query looks for direct children or all descendants
|
||||
* of the querying element, by using the `descendants` parameter.
|
||||
* It is set to `false` by default.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/wtGeB977bv7qvA5FTYl9?p=preview))
|
||||
* ```html
|
||||
* <container #first>
|
||||
* <item>a</item>
|
||||
* <item>b</item>
|
||||
* <container #second>
|
||||
* <item>c</item>
|
||||
* </container>
|
||||
* </container>
|
||||
* ```
|
||||
*
|
||||
* When querying for items, the first container will see only `a` and `b` by default,
|
||||
* but with `Query(TextDirective, {descendants: true})` it will see `c` too.
|
||||
*
|
||||
* The queried directives are kept in a depth-first pre-order with respect to their
|
||||
* positions in the DOM.
|
||||
*
|
||||
* Query does not look deep into any subcomponent views.
|
||||
*
|
||||
* Query is updated as part of the change-detection cycle. Since change detection
|
||||
* happens after construction of a directive, QueryList will always be empty when observed in the
|
||||
* constructor.
|
||||
*
|
||||
* The injected object is an unmodifiable live list.
|
||||
* See {@link QueryList} for more details.
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class QueryMetadata extends DependencyMetadata {
|
||||
/**
|
||||
* whether we want to query only direct children (false) or all
|
||||
* children (true).
|
||||
*/
|
||||
descendants: boolean;
|
||||
first: boolean;
|
||||
/**
|
||||
* The DI token to read from an element that matches the selector.
|
||||
*/
|
||||
read: any;
|
||||
|
||||
constructor(private _selector: Type | string,
|
||||
{descendants = false, first = false,
|
||||
read = null}: {descendants?: boolean, first?: boolean, read?: any} = {}) {
|
||||
super();
|
||||
this.descendants = descendants;
|
||||
this.first = first;
|
||||
this.read = read;
|
||||
}
|
||||
|
||||
/**
|
||||
* always `false` to differentiate it with {@link ViewQueryMetadata}.
|
||||
*/
|
||||
get isViewQuery(): boolean { return false; }
|
||||
|
||||
/**
|
||||
* what this is querying for.
|
||||
*/
|
||||
get selector() { return resolveForwardRef(this._selector); }
|
||||
|
||||
/**
|
||||
* whether this is querying for a variable binding or a directive.
|
||||
*/
|
||||
get isVarBindingQuery(): boolean { return isString(this.selector); }
|
||||
|
||||
/**
|
||||
* returns a list of variable bindings this is querying for.
|
||||
* Only applicable if this is a variable bindings query.
|
||||
*/
|
||||
get varBindings(): string[] { return this.selector.split(','); }
|
||||
|
||||
toString(): string { return `@Query(${stringify(this.selector)})`; }
|
||||
}
|
||||
|
||||
// TODO: add an example after ContentChildren and ViewChildren are in master
|
||||
/**
|
||||
* Configures a content query.
|
||||
*
|
||||
* Content queries are set before the `ngAfterContentInit` callback is called.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: 'someDir'
|
||||
* })
|
||||
* class SomeDir {
|
||||
* @ContentChildren(ChildDirective) contentChildren: QueryList<ChildDirective>;
|
||||
*
|
||||
* ngAfterContentInit() {
|
||||
* // contentChildren is set
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class ContentChildrenMetadata extends QueryMetadata {
|
||||
constructor(_selector: Type | string,
|
||||
{descendants = false, read = null}: {descendants?: boolean, read?: any} = {}) {
|
||||
super(_selector, {descendants: descendants, read: read});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add an example after ContentChild and ViewChild are in master
|
||||
/**
|
||||
* Configures a content query.
|
||||
*
|
||||
* Content queries are set before the `ngAfterContentInit` callback is called.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```
|
||||
* @Directive({
|
||||
* selector: 'someDir'
|
||||
* })
|
||||
* class SomeDir {
|
||||
* @ContentChild(ChildDirective) contentChild;
|
||||
*
|
||||
* ngAfterContentInit() {
|
||||
* // contentChild is set
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class ContentChildMetadata extends QueryMetadata {
|
||||
constructor(_selector: Type | string, {read = null}: {read?: any} = {}) {
|
||||
super(_selector, {descendants: true, first: true, read: read});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link QueryMetadata}, but querying the component view, instead of
|
||||
* the content children.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/eNsFHDf7YjyM6IzKxM1j?p=preview))
|
||||
*
|
||||
* ```javascript
|
||||
* @Component({
|
||||
* ...,
|
||||
* template: `
|
||||
* <item> a </item>
|
||||
* <item> b </item>
|
||||
* <item> c </item>
|
||||
* `
|
||||
* })
|
||||
* class MyComponent {
|
||||
* shown: boolean;
|
||||
*
|
||||
* constructor(private @ViewQuery(Item) items:QueryList<Item>) {
|
||||
* items.changes.subscribe(() => console.log(items.length));
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Supports the same querying parameters as {@link QueryMetadata}, except
|
||||
* `descendants`. This always queries the whole view.
|
||||
*
|
||||
* As `shown` is flipped between true and false, items will contain zero of one
|
||||
* items.
|
||||
*
|
||||
* Specifies that a {@link QueryList} should be injected.
|
||||
*
|
||||
* The injected object is an iterable and observable live list.
|
||||
* See {@link QueryList} for more details.
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class ViewQueryMetadata extends QueryMetadata {
|
||||
constructor(_selector: Type | string,
|
||||
{descendants = false, first = false,
|
||||
read = null}: {descendants?: boolean, first?: boolean, read?: any} = {}) {
|
||||
super(_selector, {descendants: descendants, first: first, read: read});
|
||||
}
|
||||
|
||||
/**
|
||||
* always `true` to differentiate it with {@link QueryMetadata}.
|
||||
*/
|
||||
get isViewQuery() { return true; }
|
||||
toString(): string { return `@ViewQuery(${stringify(this.selector)})`; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares a list of child element references.
|
||||
*
|
||||
* Angular automatically updates the list when the DOM is updated.
|
||||
*
|
||||
* `ViewChildren` takes an argument to select elements.
|
||||
*
|
||||
* - If the argument is a type, directives or components with the type will be bound.
|
||||
*
|
||||
* - If the argument is a string, the string is interpreted as a list of comma-separated selectors.
|
||||
* For each selector, an element containing the matching template variable (e.g. `#child`) will be
|
||||
* bound.
|
||||
*
|
||||
* View children are set before the `ngAfterViewInit` callback is called.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* With type selector:
|
||||
*
|
||||
* ```
|
||||
* @Component({
|
||||
* selector: 'child-cmp',
|
||||
* template: '<p>child</p>'
|
||||
* })
|
||||
* class ChildCmp {
|
||||
* doSomething() {}
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'some-cmp',
|
||||
* template: `
|
||||
* <child-cmp></child-cmp>
|
||||
* <child-cmp></child-cmp>
|
||||
* <child-cmp></child-cmp>
|
||||
* `,
|
||||
* directives: [ChildCmp]
|
||||
* })
|
||||
* class SomeCmp {
|
||||
* @ViewChildren(ChildCmp) children:QueryList<ChildCmp>;
|
||||
*
|
||||
* ngAfterViewInit() {
|
||||
* // children are set
|
||||
* this.children.toArray().forEach((child)=>child.doSomething());
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* With string selector:
|
||||
*
|
||||
* ```
|
||||
* @Component({
|
||||
* selector: 'child-cmp',
|
||||
* template: '<p>child</p>'
|
||||
* })
|
||||
* class ChildCmp {
|
||||
* doSomething() {}
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'some-cmp',
|
||||
* template: `
|
||||
* <child-cmp #child1></child-cmp>
|
||||
* <child-cmp #child2></child-cmp>
|
||||
* <child-cmp #child3></child-cmp>
|
||||
* `,
|
||||
* directives: [ChildCmp]
|
||||
* })
|
||||
* class SomeCmp {
|
||||
* @ViewChildren('child1,child2,child3') children:QueryList<ChildCmp>;
|
||||
*
|
||||
* ngAfterViewInit() {
|
||||
* // children are set
|
||||
* this.children.toArray().forEach((child)=>child.doSomething());
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class ViewChildrenMetadata extends ViewQueryMetadata {
|
||||
constructor(_selector: Type | string, {read = null}: {read?: any} = {}) {
|
||||
super(_selector, {descendants: true, read: read});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Declares a reference of child element.
|
||||
*
|
||||
* `ViewChildren` takes an argument to select elements.
|
||||
*
|
||||
* - If the argument is a type, a directive or a component with the type will be bound.
|
||||
*
|
||||
If the argument is a string, the string is interpreted as a selector. An element containing the
|
||||
matching template variable (e.g. `#child`) will be bound.
|
||||
*
|
||||
* In either case, `@ViewChild()` assigns the first (looking from above) element if there are
|
||||
multiple matches.
|
||||
*
|
||||
* View child is set before the `ngAfterViewInit` callback is called.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* With type selector:
|
||||
*
|
||||
* ```
|
||||
* @Component({
|
||||
* selector: 'child-cmp',
|
||||
* template: '<p>child</p>'
|
||||
* })
|
||||
* class ChildCmp {
|
||||
* doSomething() {}
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'some-cmp',
|
||||
* template: '<child-cmp></child-cmp>',
|
||||
* directives: [ChildCmp]
|
||||
* })
|
||||
* class SomeCmp {
|
||||
* @ViewChild(ChildCmp) child:ChildCmp;
|
||||
*
|
||||
* ngAfterViewInit() {
|
||||
* // child is set
|
||||
* this.child.doSomething();
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* With string selector:
|
||||
*
|
||||
* ```
|
||||
* @Component({
|
||||
* selector: 'child-cmp',
|
||||
* template: '<p>child</p>'
|
||||
* })
|
||||
* class ChildCmp {
|
||||
* doSomething() {}
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'some-cmp',
|
||||
* template: '<child-cmp #child></child-cmp>',
|
||||
* directives: [ChildCmp]
|
||||
* })
|
||||
* class SomeCmp {
|
||||
* @ViewChild('child') child:ChildCmp;
|
||||
*
|
||||
* ngAfterViewInit() {
|
||||
* // child is set
|
||||
* this.child.doSomething();
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class ViewChildMetadata extends ViewQueryMetadata {
|
||||
constructor(_selector: Type | string, {read = null}: {read?: any} = {}) {
|
||||
super(_selector, {descendants: true, first: true, read: read});
|
||||
}
|
||||
}
|
1132
modules/@angular/core/src/metadata/directives.ts
Normal file
1132
modules/@angular/core/src/metadata/directives.ts
Normal file
File diff suppressed because it is too large
Load Diff
477
modules/@angular/core/src/metadata/lifecycle_hooks.ts
Normal file
477
modules/@angular/core/src/metadata/lifecycle_hooks.ts
Normal file
@ -0,0 +1,477 @@
|
||||
import {SimpleChange} from 'angular2/src/core/change_detection/change_detection_util';
|
||||
|
||||
export enum LifecycleHooks {
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
DoCheck,
|
||||
OnChanges,
|
||||
AfterContentInit,
|
||||
AfterContentChecked,
|
||||
AfterViewInit,
|
||||
AfterViewChecked
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export var LIFECYCLE_HOOKS_VALUES = [
|
||||
LifecycleHooks.OnInit,
|
||||
LifecycleHooks.OnDestroy,
|
||||
LifecycleHooks.DoCheck,
|
||||
LifecycleHooks.OnChanges,
|
||||
LifecycleHooks.AfterContentInit,
|
||||
LifecycleHooks.AfterContentChecked,
|
||||
LifecycleHooks.AfterViewInit,
|
||||
LifecycleHooks.AfterViewChecked
|
||||
];
|
||||
|
||||
/**
|
||||
* Lifecycle hooks are guaranteed to be called in the following order:
|
||||
* - `OnChanges` (if any bindings have changed),
|
||||
* - `OnInit` (after the first check only),
|
||||
* - `DoCheck`,
|
||||
* - `AfterContentInit`,
|
||||
* - `AfterContentChecked`,
|
||||
* - `AfterViewInit`,
|
||||
* - `AfterViewChecked`,
|
||||
* - `OnDestroy` (at the very end before destruction)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implement this interface to get notified when any data-bound property of your directive changes.
|
||||
*
|
||||
* `ngOnChanges` is called right after the data-bound properties have been checked and before view
|
||||
* and content children are checked if at least one of them has changed.
|
||||
*
|
||||
* The `changes` parameter contains an entry for each of the changed data-bound property. The key is
|
||||
* the property name and the value is an instance of {@link SimpleChange}.
|
||||
*
|
||||
* ### Example ([live example](http://plnkr.co/edit/AHrB6opLqHDBPkt4KpdT?p=preview)):
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'my-cmp',
|
||||
* template: `<p>myProp = {{myProp}}</p>`
|
||||
* })
|
||||
* class MyComponent implements OnChanges {
|
||||
* @Input() myProp: any;
|
||||
*
|
||||
* ngOnChanges(changes: {[propName: string]: SimpleChange}) {
|
||||
* console.log('ngOnChanges - myProp = ' + changes['myProp'].currentValue);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <button (click)="value = value + 1">Change MyComponent</button>
|
||||
* <my-cmp [my-prop]="value"></my-cmp>`,
|
||||
* directives: [MyComponent]
|
||||
* })
|
||||
* export class App {
|
||||
* value = 0;
|
||||
* }
|
||||
*
|
||||
* bootstrap(App).catch(err => console.error(err));
|
||||
* ```
|
||||
*/
|
||||
export interface OnChanges { ngOnChanges(changes: {[key: string]: SimpleChange}); }
|
||||
|
||||
/**
|
||||
* Implement this interface to execute custom initialization logic after your directive's
|
||||
* data-bound properties have been initialized.
|
||||
*
|
||||
* `ngOnInit` is called right after the directive's data-bound properties have been checked for the
|
||||
* first time, and before any of its children have been checked. It is invoked only once when the
|
||||
* directive is instantiated.
|
||||
*
|
||||
* ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'my-cmp',
|
||||
* template: `<p>my-component</p>`
|
||||
* })
|
||||
* class MyComponent implements OnInit, OnDestroy {
|
||||
* ngOnInit() {
|
||||
* console.log('ngOnInit');
|
||||
* }
|
||||
*
|
||||
* ngOnDestroy() {
|
||||
* console.log('ngOnDestroy');
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <button (click)="hasChild = !hasChild">
|
||||
* {{hasChild ? 'Destroy' : 'Create'}} MyComponent
|
||||
* </button>
|
||||
* <my-cmp *ngIf="hasChild"></my-cmp>`,
|
||||
* directives: [MyComponent, NgIf]
|
||||
* })
|
||||
* export class App {
|
||||
* hasChild = true;
|
||||
* }
|
||||
*
|
||||
* bootstrap(App).catch(err => console.error(err));
|
||||
* ```
|
||||
*/
|
||||
export interface OnInit { ngOnInit(); }
|
||||
|
||||
/**
|
||||
* Implement this interface to override the default change detection algorithm for your directive.
|
||||
*
|
||||
* `ngDoCheck` gets called to check the changes in the directives instead of the default algorithm.
|
||||
*
|
||||
* The default change detection algorithm looks for differences by comparing bound-property values
|
||||
* by reference across change detection runs. When `DoCheck` is implemented, the default algorithm
|
||||
* is disabled and `ngDoCheck` is responsible for checking for changes.
|
||||
*
|
||||
* Implementing this interface allows improving performance by using insights about the component,
|
||||
* its implementation and data types of its properties.
|
||||
*
|
||||
* Note that a directive should not implement both `DoCheck` and {@link OnChanges} at the same time.
|
||||
* `ngOnChanges` would not be called when a directive implements `DoCheck`. Reaction to the changes
|
||||
* have to be handled from within the `ngDoCheck` callback.
|
||||
*
|
||||
* Use {@link KeyValueDiffers} and {@link IterableDiffers} to add your custom check mechanisms.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/QpnIlF0CR2i5bcYbHEUJ?p=preview))
|
||||
*
|
||||
* In the following example `ngDoCheck` uses an {@link IterableDiffers} to detect the updates to the
|
||||
* array `list`:
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'custom-check',
|
||||
* template: `
|
||||
* <p>Changes:</p>
|
||||
* <ul>
|
||||
* <li *ngFor="let line of logs">{{line}}</li>
|
||||
* </ul>`,
|
||||
* directives: [NgFor]
|
||||
* })
|
||||
* class CustomCheckComponent implements DoCheck {
|
||||
* @Input() list: any[];
|
||||
* differ: any;
|
||||
* logs = [];
|
||||
*
|
||||
* constructor(differs: IterableDiffers) {
|
||||
* this.differ = differs.find([]).create(null);
|
||||
* }
|
||||
*
|
||||
* ngDoCheck() {
|
||||
* var changes = this.differ.diff(this.list);
|
||||
*
|
||||
* if (changes) {
|
||||
* changes.forEachAddedItem(r => this.logs.push('added ' + r.item));
|
||||
* changes.forEachRemovedItem(r => this.logs.push('removed ' + r.item))
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <button (click)="list.push(list.length)">Push</button>
|
||||
* <button (click)="list.pop()">Pop</button>
|
||||
* <custom-check [list]="list"></custom-check>`,
|
||||
* directives: [CustomCheckComponent]
|
||||
* })
|
||||
* export class App {
|
||||
* list = [];
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface DoCheck { ngDoCheck(); }
|
||||
|
||||
/**
|
||||
* Implement this interface to get notified when your directive is destroyed.
|
||||
*
|
||||
* `ngOnDestroy` callback is typically used for any custom cleanup that needs to occur when the
|
||||
* instance is destroyed
|
||||
*
|
||||
* ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
|
||||
*
|
||||
* ```typesript
|
||||
* @Component({
|
||||
* selector: 'my-cmp',
|
||||
* template: `<p>my-component</p>`
|
||||
* })
|
||||
* class MyComponent implements OnInit, OnDestroy {
|
||||
* ngOnInit() {
|
||||
* console.log('ngOnInit');
|
||||
* }
|
||||
*
|
||||
* ngOnDestroy() {
|
||||
* console.log('ngOnDestroy');
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <button (click)="hasChild = !hasChild">
|
||||
* {{hasChild ? 'Destroy' : 'Create'}} MyComponent
|
||||
* </button>
|
||||
* <my-cmp *ngIf="hasChild"></my-cmp>`,
|
||||
* directives: [MyComponent, NgIf]
|
||||
* })
|
||||
* export class App {
|
||||
* hasChild = true;
|
||||
* }
|
||||
*
|
||||
* bootstrap(App).catch(err => console.error(err));
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* To create a stateful Pipe, you should implement this interface and set the `pure`
|
||||
* parameter to `false` in the {@link PipeMetadata}.
|
||||
*
|
||||
* A stateful pipe may produce different output, given the same input. It is
|
||||
* likely that a stateful pipe may contain state that should be cleaned up when
|
||||
* a binding is destroyed. For example, a subscription to a stream of data may need to
|
||||
* be disposed, or an interval may need to be cleared.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/i8pm5brO4sPaLxBx56MR?p=preview))
|
||||
*
|
||||
* In this example, a pipe is created to countdown its input value, updating it every
|
||||
* 50ms. Because it maintains an internal interval, it automatically clears
|
||||
* the interval when the binding is destroyed or the countdown completes.
|
||||
*
|
||||
* ```
|
||||
* import {OnDestroy, Pipe, PipeTransform} from 'angular2/core'
|
||||
* @Pipe({name: 'countdown', pure: false})
|
||||
* class CountDown implements PipeTransform, OnDestroy {
|
||||
* remainingTime:Number;
|
||||
* interval:SetInterval;
|
||||
* ngOnDestroy() {
|
||||
* if (this.interval) {
|
||||
* clearInterval(this.interval);
|
||||
* }
|
||||
* }
|
||||
* transform(value: any, args: any[] = []) {
|
||||
* if (!parseInt(value, 10)) return null;
|
||||
* if (typeof this.remainingTime !== 'number') {
|
||||
* this.remainingTime = parseInt(value, 10);
|
||||
* }
|
||||
* if (!this.interval) {
|
||||
* this.interval = setInterval(() => {
|
||||
* this.remainingTime-=50;
|
||||
* if (this.remainingTime <= 0) {
|
||||
* this.remainingTime = 0;
|
||||
* clearInterval(this.interval);
|
||||
* delete this.interval;
|
||||
* }
|
||||
* }, 50);
|
||||
* }
|
||||
* return this.remainingTime;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Invoking `{{ 10000 | countdown }}` would cause the value to be decremented by 50,
|
||||
* every 50ms, until it reaches 0.
|
||||
*
|
||||
*/
|
||||
export interface OnDestroy { ngOnDestroy(); }
|
||||
|
||||
/**
|
||||
* Implement this interface to get notified when your directive's content has been fully
|
||||
* initialized.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/plamXUpsLQbIXpViZhUO?p=preview))
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'child-cmp',
|
||||
* template: `{{where}} child`
|
||||
* })
|
||||
* class ChildComponent {
|
||||
* @Input() where: string;
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'parent-cmp',
|
||||
* template: `<ng-content></ng-content>`
|
||||
* })
|
||||
* class ParentComponent implements AfterContentInit {
|
||||
* @ContentChild(ChildComponent) contentChild: ChildComponent;
|
||||
*
|
||||
* constructor() {
|
||||
* // contentChild is not initialized yet
|
||||
* console.log(this.getMessage(this.contentChild));
|
||||
* }
|
||||
*
|
||||
* ngAfterContentInit() {
|
||||
* // contentChild is updated after the content has been checked
|
||||
* console.log('AfterContentInit: ' + this.getMessage(this.contentChild));
|
||||
* }
|
||||
*
|
||||
* private getMessage(cmp: ChildComponent): string {
|
||||
* return cmp ? cmp.where + ' child' : 'no child';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <parent-cmp>
|
||||
* <child-cmp where="content"></child-cmp>
|
||||
* </parent-cmp>`,
|
||||
* directives: [ParentComponent, ChildComponent]
|
||||
* })
|
||||
* export class App {
|
||||
* }
|
||||
*
|
||||
* bootstrap(App).catch(err => console.error(err));
|
||||
* ```
|
||||
*/
|
||||
export interface AfterContentInit { ngAfterContentInit(); }
|
||||
|
||||
/**
|
||||
* Implement this interface to get notified after every check of your directive's content.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/tGdrytNEKQnecIPkD7NU?p=preview))
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({selector: 'child-cmp', template: `{{where}} child`})
|
||||
* class ChildComponent {
|
||||
* @Input() where: string;
|
||||
* }
|
||||
*
|
||||
* @Component({selector: 'parent-cmp', template: `<ng-content></ng-content>`})
|
||||
* class ParentComponent implements AfterContentChecked {
|
||||
* @ContentChild(ChildComponent) contentChild: ChildComponent;
|
||||
*
|
||||
* constructor() {
|
||||
* // contentChild is not initialized yet
|
||||
* console.log(this.getMessage(this.contentChild));
|
||||
* }
|
||||
*
|
||||
* ngAfterContentChecked() {
|
||||
* // contentChild is updated after the content has been checked
|
||||
* console.log('AfterContentChecked: ' + this.getMessage(this.contentChild));
|
||||
* }
|
||||
*
|
||||
* private getMessage(cmp: ChildComponent): string {
|
||||
* return cmp ? cmp.where + ' child' : 'no child';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `
|
||||
* <parent-cmp>
|
||||
* <button (click)="hasContent = !hasContent">Toggle content child</button>
|
||||
* <child-cmp *ngIf="hasContent" where="content"></child-cmp>
|
||||
* </parent-cmp>`,
|
||||
* directives: [NgIf, ParentComponent, ChildComponent]
|
||||
* })
|
||||
* export class App {
|
||||
* hasContent = true;
|
||||
* }
|
||||
*
|
||||
* bootstrap(App).catch(err => console.error(err));
|
||||
* ```
|
||||
*/
|
||||
export interface AfterContentChecked { ngAfterContentChecked(); }
|
||||
|
||||
/**
|
||||
* Implement this interface to get notified when your component's view has been fully initialized.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/LhTKVMEM0fkJgyp4CI1W?p=preview))
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({selector: 'child-cmp', template: `{{where}} child`})
|
||||
* class ChildComponent {
|
||||
* @Input() where: string;
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'parent-cmp',
|
||||
* template: `<child-cmp where="view"></child-cmp>`,
|
||||
* directives: [ChildComponent]
|
||||
* })
|
||||
* class ParentComponent implements AfterViewInit {
|
||||
* @ViewChild(ChildComponent) viewChild: ChildComponent;
|
||||
*
|
||||
* constructor() {
|
||||
* // viewChild is not initialized yet
|
||||
* console.log(this.getMessage(this.viewChild));
|
||||
* }
|
||||
*
|
||||
* ngAfterViewInit() {
|
||||
* // viewChild is updated after the view has been initialized
|
||||
* console.log('ngAfterViewInit: ' + this.getMessage(this.viewChild));
|
||||
* }
|
||||
*
|
||||
* private getMessage(cmp: ChildComponent): string {
|
||||
* return cmp ? cmp.where + ' child' : 'no child';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `<parent-cmp></parent-cmp>`,
|
||||
* directives: [ParentComponent]
|
||||
* })
|
||||
* export class App {
|
||||
* }
|
||||
*
|
||||
* bootstrap(App).catch(err => console.error(err));
|
||||
* ```
|
||||
*/
|
||||
export interface AfterViewInit { ngAfterViewInit(); }
|
||||
|
||||
/**
|
||||
* Implement this interface to get notified after every check of your component's view.
|
||||
*
|
||||
* ### Example ([live demo](http://plnkr.co/edit/0qDGHcPQkc25CXhTNzKU?p=preview))
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({selector: 'child-cmp', template: `{{where}} child`})
|
||||
* class ChildComponent {
|
||||
* @Input() where: string;
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'parent-cmp',
|
||||
* template: `
|
||||
* <button (click)="showView = !showView">Toggle view child</button>
|
||||
* <child-cmp *ngIf="showView" where="view"></child-cmp>`,
|
||||
* directives: [NgIf, ChildComponent]
|
||||
* })
|
||||
* class ParentComponent implements AfterViewChecked {
|
||||
* @ViewChild(ChildComponent) viewChild: ChildComponent;
|
||||
* showView = true;
|
||||
*
|
||||
* constructor() {
|
||||
* // viewChild is not initialized yet
|
||||
* console.log(this.getMessage(this.viewChild));
|
||||
* }
|
||||
*
|
||||
* ngAfterViewChecked() {
|
||||
* // viewChild is updated after the view has been checked
|
||||
* console.log('AfterViewChecked: ' + this.getMessage(this.viewChild));
|
||||
* }
|
||||
*
|
||||
* private getMessage(cmp: ChildComponent): string {
|
||||
* return cmp ? cmp.where + ' child' : 'no child';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Component({
|
||||
* selector: 'app',
|
||||
* template: `<parent-cmp></parent-cmp>`,
|
||||
* directives: [ParentComponent]
|
||||
* })
|
||||
* export class App {
|
||||
* }
|
||||
*
|
||||
* bootstrap(App).catch(err => console.error(err));
|
||||
* ```
|
||||
*/
|
||||
export interface AfterViewChecked { ngAfterViewChecked(); }
|
143
modules/@angular/core/src/metadata/view.ts
Normal file
143
modules/@angular/core/src/metadata/view.ts
Normal file
@ -0,0 +1,143 @@
|
||||
import {Type} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
* Defines template and style encapsulation options available for Component's {@link View}.
|
||||
*
|
||||
* See {@link ViewMetadata#encapsulation}.
|
||||
*/
|
||||
export enum ViewEncapsulation {
|
||||
/**
|
||||
* Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
|
||||
* Element and pre-processing the style rules provided via
|
||||
* {@link ViewMetadata#styles} or {@link ViewMetadata#stylesUrls}, and adding the new Host Element
|
||||
* attribute to all selectors.
|
||||
*
|
||||
* This is the default option.
|
||||
*/
|
||||
Emulated,
|
||||
/**
|
||||
* Use the native encapsulation mechanism of the renderer.
|
||||
*
|
||||
* For the DOM this means using [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
|
||||
* creating a ShadowRoot for Component's Host Element.
|
||||
*/
|
||||
Native,
|
||||
/**
|
||||
* Don't provide any template or style encapsulation.
|
||||
*/
|
||||
None
|
||||
}
|
||||
|
||||
export var VIEW_ENCAPSULATION_VALUES =
|
||||
[ViewEncapsulation.Emulated, ViewEncapsulation.Native, ViewEncapsulation.None];
|
||||
|
||||
|
||||
/**
|
||||
* Metadata properties available for configuring Views.
|
||||
*
|
||||
* 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 ComponentMetadata}.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```
|
||||
* @Component({
|
||||
* selector: 'greet',
|
||||
* template: 'Hello {{name}}!',
|
||||
* directives: [GreetUser, Bold]
|
||||
* })
|
||||
* class Greet {
|
||||
* name: string;
|
||||
*
|
||||
* constructor() {
|
||||
* this.name = 'World';
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* @ts2dart_const
|
||||
*/
|
||||
export class ViewMetadata {
|
||||
/**
|
||||
* Specifies a template URL for an Angular component.
|
||||
*
|
||||
* NOTE: Only one of `templateUrl` or `template` can be defined per View.
|
||||
*
|
||||
* <!-- TODO: what's the url relative to? -->
|
||||
*/
|
||||
templateUrl: string;
|
||||
|
||||
/**
|
||||
* Specifies an inline template for an Angular component.
|
||||
*
|
||||
* NOTE: Only one of `templateUrl` or `template` can be defined per View.
|
||||
*/
|
||||
template: string;
|
||||
|
||||
/**
|
||||
* Specifies stylesheet URLs for an Angular component.
|
||||
*
|
||||
* <!-- TODO: what's the url relative to? -->
|
||||
*/
|
||||
styleUrls: string[];
|
||||
|
||||
/**
|
||||
* Specifies an inline stylesheet for an Angular component.
|
||||
*/
|
||||
styles: 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',
|
||||
* directives: [NgFor]
|
||||
* template: '
|
||||
* <ul>
|
||||
* <li *ngFor="let item of items">{{item}}</li>
|
||||
* </ul>'
|
||||
* })
|
||||
* class MyComponent {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
directives: Array<Type | any[]>;
|
||||
|
||||
pipes: Array<Type | any[]>;
|
||||
|
||||
/**
|
||||
* Specify how the template and the styles should be encapsulated.
|
||||
* The default is {@link ViewEncapsulation#Emulated `ViewEncapsulation.Emulated`} if the view
|
||||
* has styles,
|
||||
* otherwise {@link ViewEncapsulation#None `ViewEncapsulation.None`}.
|
||||
*/
|
||||
encapsulation: ViewEncapsulation;
|
||||
|
||||
constructor({templateUrl, template, directives, pipes, encapsulation, styles, styleUrls}: {
|
||||
templateUrl?: string,
|
||||
template?: string,
|
||||
directives?: Array<Type | any[]>,
|
||||
pipes?: Array<Type | any[]>,
|
||||
encapsulation?: ViewEncapsulation,
|
||||
styles?: string[],
|
||||
styleUrls?: string[],
|
||||
} = {}) {
|
||||
this.templateUrl = templateUrl;
|
||||
this.template = template;
|
||||
this.styleUrls = styleUrls;
|
||||
this.styles = styles;
|
||||
this.directives = directives;
|
||||
this.pipes = pipes;
|
||||
this.encapsulation = encapsulation;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user