doc(LifecycleHooks): update API doc

Closes #4357
This commit is contained in:
Victor Berchet 2015-09-24 15:40:50 -07:00
parent e8e57cdd73
commit a110ce95dc
1 changed files with 318 additions and 78 deletions

View File

@ -1,6 +1,9 @@
import {StringMap, MapWrapper} from 'angular2/src/core/facade/collection'; import {StringMap, MapWrapper} from 'angular2/src/core/facade/collection';
import {SimpleChange} from 'angular2/src/core/change_detection/change_detection_util'; import {SimpleChange} from 'angular2/src/core/change_detection/change_detection_util';
/**
* @private
*/
export enum LifecycleHooks { export enum LifecycleHooks {
OnInit, OnInit,
OnDestroy, OnDestroy,
@ -12,6 +15,9 @@ export enum LifecycleHooks {
AfterViewChecked AfterViewChecked
} }
/**
* @private
*/
export var LIFECYCLE_HOOKS_VALUES = [ export var LIFECYCLE_HOOKS_VALUES = [
LifecycleHooks.OnInit, LifecycleHooks.OnInit,
LifecycleHooks.OnDestroy, LifecycleHooks.OnDestroy,
@ -30,156 +36,390 @@ export var LIFECYCLE_HOOKS_VALUES = [
* - `DoCheck`, * - `DoCheck`,
* - `AfterContentInit`, * - `AfterContentInit`,
* - `AfterContentChecked`, * - `AfterContentChecked`,
* - `AfterViewInit`,
* - `AfterViewChecked`,
* - `OnDestroy` (at the very end before destruction) * - `OnDestroy` (at the very end before destruction)
*/ */
/** /**
* Notify a directive when any of its bindings have changed. * Implement this interface to get notified when any data-bound property of your directive changes.
* *
* `onChanges` is called right after the directive's bindings have been checked, * `onChanges` is called right after the data-bound properties have been checked and before view
* and before any of its children's bindings have been checked. * and content children are checked if at least one of them has changed.
* *
* It is invoked only if at least one of the directive's bindings 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: * ### Example ([live example](http://plnkr.co/edit/AHrB6opLqHDBPkt4KpdT?p=preview)):
* *
* ``` * ```typescript
* @Component(...) * @Component({selector: 'my-cmp'})
* @View({template: `<p>myProp = {{myProp}}</p>`})
* class MyComponent implements OnChanges { * class MyComponent implements OnChanges {
* propA; * @Property() myProp: any;
* propB;
* *
* onChanges(changes: {[idx: string, PropertyUpdate]}): void { * onChanges(changes: {[propName: string]: SimpleChange}) {
* // This will get called after any of the inputs have been updated. * console.log('onChanges - myProp = ' + changes['myProp'].currentValue);
* if (changes['propA']) {
* // if propA was updated
* }
* if (changes['propA']) {
* // if propB was updated
* }
* } * }
* } * }
* ``` *
* @Component({selector: 'app'})
* @View({
* 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 { onChanges(changes: StringMap<string, SimpleChange>); } export interface OnChanges { onChanges(changes: StringMap<string, SimpleChange>); }
/** /**
* Notify a directive when it has been checked the first time. * Implement this interface to execute custom initialization logic after your directive's
* data-bound properties have been initialized.
* *
* `onInit` is called right after the directive's bindings have been checked for the first time, * `onInit` is called right after the directive's data-bound properties have been checked for the
* and before any of its children's bindings have been checked. * first time, and before any of its children have been checked. It is invoked only once when the
* directive is instantiated.
* *
* It is invoked only once. * ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
* *
* ## Example * ```typescript
* @Component({selector: 'my-cmp'})
* @View({template: `<p>my-component</p>`})
* class MyComponent implements OnInit, OnDestroy {
* onInit() {
* console.log('onInit');
* }
* *
* ``` * onDestroy() {
* @Component(...) * console.log('onDestroy');
* class MyComponent implements OnInit {
* onInit(): void {
* } * }
* } * }
*
* @Component({selector: 'app'})
* @View({
* template: `
* <button (click)="hasChild = !hasChild">
* {{hasChild ? 'Destroy' : 'Create'}} MyComponent
* </button>
* <my-cmp *ng-if="hasChild"></my-cmp>`,
* directives: [MyComponent, NgIf]
* })
* export class App {
* hasChild = true;
* }
*
* bootstrap(App).catch(err => console.error(err));
* ``` * ```
*/ */
export interface OnInit { onInit(); } export interface OnInit { onInit(); }
/** /**
* Overrides the default change detection. * Implement this interface to override the default change detection algorithm for your directive.
* *
* `doCheck()` gets called to check the changes in the directives instead of the default * `doCheck` gets called to check the changes in the directives instead of the default algorithm.
* change detection mechanism.
* *
* It is invoked every time the change detection is triggered. * 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 `doCheck` is responsible for checking for changes.
* *
* ## Example * 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.
* @Component(...) * `onChanges` would not be called when a directive implements `DoCheck`. Reaction to the changes
* class MyComponent implements DoCheck { * have to be handled from within the `doCheck` callback.
* doCheck(): void { *
* // Custom logic to detect changes * 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 `doCheck` uses an {@link IterableDiffers} to detect the updates to the
* array `list`:
*
* ```typescript
* @Component({selector: 'custom-check'})
* @View({
* template: `
* <p>Changes:</p>
* <ul>
* <li *ng-for="#line of logs">{{line}}</li>
* </ul>`,
* directives: [NgFor]
* })
* class CustomCheckComponent implements DoCheck {
* @Property() list: any[];
* differ: any;
* logs = [];
*
* constructor(differs: IterableDiffers) {
* this.differ = differs.find([]).create(null);
* }
*
* doCheck() {
* 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'})
* @View({
* 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 { doCheck(); } export interface DoCheck { doCheck(); }
/** /**
* Notify a directive whenever a {@link ViewMetadata} that contains it is destroyed. * Implement this interface to get notified when your directive is destroyed.
* *
* ## Example * `onDestroy` 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))
* @Component(...) *
* class MyComponent implements OnDestroy { * ```typesript
* onDestroy(): void { * @Component({selector: 'my-cmp'})
* // invoked to notify directive of the containing view destruction. * @View({template: `<p>my-component</p>`})
* class MyComponent implements OnInit, OnDestroy {
* onInit() {
* console.log('onInit');
* }
*
* onDestroy() {
* console.log('onDestroy');
* } * }
* } * }
* ``` *
* @Component({selector: 'app'})
* @View({
* template: `
* <button (click)="hasChild = !hasChild">
* {{hasChild ? 'Destroy' : 'Create'}} MyComponent
* </button>
* <my-cmp *ng-if="hasChild"></my-cmp>`,
* directives: [MyComponent, NgIf]
* })
* export class App {
* hasChild = true;
* }
*
* bootstrap(App).catch(err => console.error(err));
* * ```
*/ */
export interface OnDestroy { onDestroy(); } export interface OnDestroy { onDestroy(); }
/** /**
* Notify a directive when the bindings of all its content children have been checked the first * Implement this interface to get notified when your directive's content has been fully
* time (whether they have changed or not). * initialized.
* *
* ## Example * ### Example ([live demo](http://plnkr.co/edit/plamXUpsLQbIXpViZhUO?p=preview))
* *
* ``` * ```typescript
* @Component(...) * @Component({selector: 'child-cmp'})
* class MyComponent implements AfterContentInit { * @View({template: `{{where}} child`})
* afterContentInit(): void { * class ChildComponent {
* @Property() where: string;
* }
*
* @Component({selector: 'parent-cmp'})
* @View({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));
* }
*
* afterContentInit() {
* // 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'})
* @View({
* 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 { afterContentInit(); } export interface AfterContentInit { afterContentInit(); }
/** /**
* Notify a directive when the bindings of all its content children have been checked (whether * Implement this interface to get notified after every check of your directive's content.
* they have changed or not).
* *
* ## Example * ### Example ([live demo](http://plnkr.co/edit/tGdrytNEKQnecIPkD7NU?p=preview))
* *
* ``` * ```typescript
* @Component(...) * @Component({selector: 'child-cmp'})
* class MyComponent implements AfterContentChecked { * @View({template: `{{where}} child`})
* afterContentChecked(): void { * class ChildComponent {
* @Property() where: string;
* }
*
* @Component({selector: 'parent-cmp'})
* @View({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));
* }
*
* afterContentChecked() {
* // 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'})
* @View({
* template: `
* <parent-cmp>
* <button (click)="hasContent = !hasContent">Toggle content child</button>
* <child-cmp *ng-if="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 { afterContentChecked(); } export interface AfterContentChecked { afterContentChecked(); }
/** /**
* Notify a directive when the bindings of all its view children have been checked the first time * Implement this interface to get notified when your component's view has been fully initialized.
* (whether they have changed or not).
* *
* ## Example * ### Example ([live demo](http://plnkr.co/edit/LhTKVMEM0fkJgyp4CI1W?p=preview))
* *
* ``` * ```typescript
* @Component(...) * @Component({selector: 'child-cmp'})
* class MyComponent implements AfterViewInit { * @View({template: `{{where}} child`})
* afterViewInit(): void { * class ChildComponent {
* @Property() where: string;
* }
*
* @Component({selector: 'parent-cmp'})
* @View({
* 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));
* }
*
* afterViewInit() {
* // viewChild is updated after the view has been initialized
* console.log('afterViewInit: ' + this.getMessage(this.viewChild));
* }
*
* private getMessage(cmp: ChildComponent): string {
* return cmp ? cmp.where + ' child' : 'no child';
* } * }
* } * }
* ``` *
* @Component({selector: 'app'})
* @View({
* template: `<parent-cmp></parent-cmp>`,
* directives: [ParentComponent]
* })
* export class App {
* }
*
* bootstrap(App).catch(err => console.error(err));
* ```
*/ */
export interface AfterViewInit { afterViewInit(); } export interface AfterViewInit { afterViewInit(); }
/** /**
* Notify a directive when the bindings of all its view children have been checked (whether they * Implement this interface to get notified after every check of your component's view.
* have changed or not).
* *
* ## Example * ### Example ([live demo](http://plnkr.co/edit/0qDGHcPQkc25CXhTNzKU?p=preview))
* *
* ``` * ```typescript
* @Component(...) * @Component({selector: 'child-cmp'})
* class MyComponent implements AfterViewChecked { * @View({template: `{{where}} child`})
* afterViewChecked(): void { * class ChildComponent {
* @Property() where: string;
* }
*
* @Component({selector: 'parent-cmp'})
* @View({
* template: `
* <button (click)="showView = !showView">Toggle view child</button>
* <child-cmp *ng-if="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));
* }
*
* afterViewChecked() {
* // 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'})
* @View({
* template: `<parent-cmp></parent-cmp>`,
* directives: [ParentComponent]
* })
* export class App {
* }
*
* bootstrap(App).catch(err => console.error(err));
* ```
*/ */
export interface AfterViewChecked { afterViewChecked(); } export interface AfterViewChecked { afterViewChecked(); }