2015-10-02 19:47:54 -04:00
|
|
|
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
2015-09-23 14:43:31 -04:00
|
|
|
import {SimpleChange} from 'angular2/src/core/change_detection/change_detection_util';
|
2015-05-22 16:14:59 -04:00
|
|
|
|
2015-09-11 17:23:24 -04:00
|
|
|
export enum LifecycleHooks {
|
|
|
|
OnInit,
|
|
|
|
OnDestroy,
|
|
|
|
DoCheck,
|
|
|
|
OnChanges,
|
|
|
|
AfterContentInit,
|
|
|
|
AfterContentChecked,
|
|
|
|
AfterViewInit,
|
|
|
|
AfterViewChecked
|
|
|
|
}
|
|
|
|
|
2015-09-24 18:40:50 -04:00
|
|
|
/**
|
2015-10-02 16:32:48 -04:00
|
|
|
* @internal
|
2015-09-24 18:40:50 -04:00
|
|
|
*/
|
2015-09-18 13:33:23 -04:00
|
|
|
export var LIFECYCLE_HOOKS_VALUES = [
|
|
|
|
LifecycleHooks.OnInit,
|
|
|
|
LifecycleHooks.OnDestroy,
|
|
|
|
LifecycleHooks.DoCheck,
|
|
|
|
LifecycleHooks.OnChanges,
|
|
|
|
LifecycleHooks.AfterContentInit,
|
|
|
|
LifecycleHooks.AfterContentChecked,
|
|
|
|
LifecycleHooks.AfterViewInit,
|
|
|
|
LifecycleHooks.AfterViewChecked
|
|
|
|
];
|
|
|
|
|
2015-05-22 16:14:59 -04:00
|
|
|
/**
|
2015-08-31 21:32:32 -04:00
|
|
|
* 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`,
|
2015-09-24 18:40:50 -04:00
|
|
|
* - `AfterViewInit`,
|
|
|
|
* - `AfterViewChecked`,
|
2015-08-31 21:32:32 -04:00
|
|
|
* - `OnDestroy` (at the very end before destruction)
|
2015-05-22 16:14:59 -04:00
|
|
|
*/
|
2015-05-27 11:07:37 -04:00
|
|
|
|
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to get notified when any data-bound property of your directive changes.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* `onChanges` 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.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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}.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ### Example ([live example](http://plnkr.co/edit/AHrB6opLqHDBPkt4KpdT?p=preview)):
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ```typescript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'my-cmp',
|
|
|
|
* template: `<p>myProp = {{myProp}}</p>`
|
|
|
|
* })
|
2015-08-31 21:32:32 -04:00
|
|
|
* class MyComponent implements OnChanges {
|
2015-10-10 13:04:13 -04:00
|
|
|
* @Input() myProp: any;
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* onChanges(changes: {[propName: string]: SimpleChange}) {
|
|
|
|
* console.log('onChanges - myProp = ' + changes['myProp'].currentValue);
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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));
|
|
|
|
* ```
|
2015-05-27 11:07:37 -04:00
|
|
|
*/
|
2015-10-02 19:47:54 -04:00
|
|
|
export interface OnChanges { onChanges(changes: {[key: string]: SimpleChange}); }
|
2015-05-27 11:07:37 -04:00
|
|
|
|
2015-05-27 13:14:37 -04:00
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to execute custom initialization logic after your directive's
|
|
|
|
* data-bound properties have been initialized.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* `onInit` 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.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ```typescript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'my-cmp',
|
|
|
|
* template: `<p>my-component</p>`
|
|
|
|
* })
|
2015-09-24 18:40:50 -04:00
|
|
|
* class MyComponent implements OnInit, OnDestroy {
|
|
|
|
* onInit() {
|
|
|
|
* console.log('onInit');
|
|
|
|
* }
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* onDestroy() {
|
|
|
|
* console.log('onDestroy');
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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));
|
2015-08-31 21:32:32 -04:00
|
|
|
* ```
|
2015-05-27 13:14:37 -04:00
|
|
|
*/
|
2015-09-11 17:23:24 -04:00
|
|
|
export interface OnInit { onInit(); }
|
2015-05-27 13:14:37 -04:00
|
|
|
|
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to override the default change detection algorithm for your directive.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* `doCheck` gets called to check the changes in the directives instead of the default algorithm.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implementing this interface allows improving performance by using insights about the component,
|
|
|
|
* its implementation and data types of its properties.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* Note that a directive should not implement both `DoCheck` and {@link OnChanges} at the same time.
|
|
|
|
* `onChanges` would not be called when a directive implements `DoCheck`. Reaction to the changes
|
|
|
|
* have to be handled from within the `doCheck` 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 `doCheck` uses an {@link IterableDiffers} to detect the updates to the
|
|
|
|
* array `list`:
|
|
|
|
*
|
|
|
|
* ```typescript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'custom-check',
|
2015-09-24 18:40:50 -04:00
|
|
|
* template: `
|
|
|
|
* <p>Changes:</p>
|
|
|
|
* <ul>
|
|
|
|
* <li *ng-for="#line of logs">{{line}}</li>
|
|
|
|
* </ul>`,
|
|
|
|
* directives: [NgFor]
|
|
|
|
* })
|
|
|
|
* class CustomCheckComponent implements DoCheck {
|
2015-10-10 13:04:13 -04:00
|
|
|
* @Input() list: any[];
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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))
|
|
|
|
* }
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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 = [];
|
|
|
|
* }
|
|
|
|
* ```
|
2015-05-27 13:14:37 -04:00
|
|
|
*/
|
2015-09-11 17:23:24 -04:00
|
|
|
export interface DoCheck { doCheck(); }
|
2015-05-27 13:14:37 -04:00
|
|
|
|
2015-08-28 21:11:04 -04:00
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to get notified when your directive is destroyed.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* `onDestroy` callback is typically used for any custom cleanup that needs to occur when the
|
|
|
|
* instance is destroyed
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
|
|
|
|
*
|
|
|
|
* ```typesript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'my-cmp',
|
|
|
|
* template: `<p>my-component</p>`
|
|
|
|
* })
|
2015-09-24 18:40:50 -04:00
|
|
|
* class MyComponent implements OnInit, OnDestroy {
|
|
|
|
* onInit() {
|
|
|
|
* console.log('onInit');
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* onDestroy() {
|
|
|
|
* console.log('onDestroy');
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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));
|
|
|
|
* * ```
|
2015-08-28 21:11:04 -04:00
|
|
|
*/
|
2015-09-11 17:23:24 -04:00
|
|
|
export interface OnDestroy { onDestroy(); }
|
2015-08-28 21:11:04 -04:00
|
|
|
|
2015-05-27 11:07:37 -04:00
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to get notified when your directive's content has been fully
|
|
|
|
* initialized.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ### Example ([live demo](http://plnkr.co/edit/plamXUpsLQbIXpViZhUO?p=preview))
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ```typescript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'child-cmp',
|
|
|
|
* template: `{{where}} child`
|
|
|
|
* })
|
2015-09-24 18:40:50 -04:00
|
|
|
* class ChildComponent {
|
2015-10-10 13:04:13 -04:00
|
|
|
* @Input() where: string;
|
2015-09-24 18:40:50 -04:00
|
|
|
* }
|
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'parent-cmp',
|
|
|
|
* template: `<ng-content></ng-content>`
|
|
|
|
* })
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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';
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* template: `
|
|
|
|
* <parent-cmp>
|
|
|
|
* <child-cmp where="content"></child-cmp>
|
|
|
|
* </parent-cmp>`,
|
|
|
|
* directives: [ParentComponent, ChildComponent]
|
|
|
|
* })
|
|
|
|
* export class App {
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* bootstrap(App).catch(err => console.error(err));
|
|
|
|
* ```
|
2015-05-27 11:07:37 -04:00
|
|
|
*/
|
2015-09-11 17:23:24 -04:00
|
|
|
export interface AfterContentInit { afterContentInit(); }
|
2015-08-28 21:11:04 -04:00
|
|
|
|
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to get notified after every check of your directive's content.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ### Example ([live demo](http://plnkr.co/edit/tGdrytNEKQnecIPkD7NU?p=preview))
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ```typescript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({selector: 'child-cmp', template: `{{where}} child`})
|
2015-09-24 18:40:50 -04:00
|
|
|
* class ChildComponent {
|
2015-10-10 13:04:13 -04:00
|
|
|
* @Input() where: string;
|
2015-09-24 18:40:50 -04:00
|
|
|
* }
|
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({selector: 'parent-cmp', template: `<ng-content></ng-content>`})
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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';
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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));
|
|
|
|
* ```
|
2015-08-28 21:11:04 -04:00
|
|
|
*/
|
2015-09-11 17:23:24 -04:00
|
|
|
export interface AfterContentChecked { afterContentChecked(); }
|
2015-08-28 21:11:04 -04:00
|
|
|
|
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to get notified when your component's view has been fully initialized.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ### Example ([live demo](http://plnkr.co/edit/LhTKVMEM0fkJgyp4CI1W?p=preview))
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ```typescript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({selector: 'child-cmp', template: `{{where}} child`})
|
2015-09-24 18:40:50 -04:00
|
|
|
* class ChildComponent {
|
2015-10-10 13:04:13 -04:00
|
|
|
* @Input() where: string;
|
2015-09-24 18:40:50 -04:00
|
|
|
* }
|
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'parent-cmp',
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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';
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* template: `<parent-cmp></parent-cmp>`,
|
|
|
|
* directives: [ParentComponent]
|
|
|
|
* })
|
|
|
|
* export class App {
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* bootstrap(App).catch(err => console.error(err));
|
|
|
|
* ```
|
2015-08-28 21:11:04 -04:00
|
|
|
*/
|
2015-09-11 17:23:24 -04:00
|
|
|
export interface AfterViewInit { afterViewInit(); }
|
2015-08-31 21:32:32 -04:00
|
|
|
|
|
|
|
/**
|
2015-09-24 18:40:50 -04:00
|
|
|
* Implement this interface to get notified after every check of your component's view.
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ### Example ([live demo](http://plnkr.co/edit/0qDGHcPQkc25CXhTNzKU?p=preview))
|
2015-08-31 21:32:32 -04:00
|
|
|
*
|
2015-09-24 18:40:50 -04:00
|
|
|
* ```typescript
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({selector: 'child-cmp', template: `{{where}} child`})
|
2015-09-24 18:40:50 -04:00
|
|
|
* class ChildComponent {
|
2015-10-10 13:04:13 -04:00
|
|
|
* @Input() where: string;
|
2015-09-24 18:40:50 -04:00
|
|
|
* }
|
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'parent-cmp',
|
2015-09-24 18:40:50 -04:00
|
|
|
* 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';
|
2015-08-31 21:32:32 -04:00
|
|
|
* }
|
|
|
|
* }
|
2015-09-24 18:40:50 -04:00
|
|
|
*
|
2015-10-11 10:41:19 -04:00
|
|
|
* @Component({
|
|
|
|
* selector: 'app',
|
2015-09-24 18:40:50 -04:00
|
|
|
* template: `<parent-cmp></parent-cmp>`,
|
|
|
|
* directives: [ParentComponent]
|
|
|
|
* })
|
|
|
|
* export class App {
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* bootstrap(App).catch(err => console.error(err));
|
|
|
|
* ```
|
2015-08-31 21:32:32 -04:00
|
|
|
*/
|
2015-09-11 17:23:24 -04:00
|
|
|
export interface AfterViewChecked { afterViewChecked(); }
|