Interface
Lifecycle hooks:
- OnInit
- OnChanges
- DoCheck
- AfterContentInit
- AfterContentChecked
- AfterViewInit
- AfterViewChecked
- OnDestroy
OnInit
Implement this interface to execute custom initialization logic after your directive's data-bound properties have been initialized.
ngOnInit
method:
- will be called on each controller(directive or component class) after all the controllers on
an element have been constructed and had their bindings initialized
This is a preferred place to put initialization code for your controller(component/directive) - is only invoked once when the directive is instantiated
NOTE:
Don't put initialization logic to
constructor
because if you inject locals(directives,components) they are not defined untilngOnInit
is triggeredIn angular 1 terms, it is called from preLink In next major version (ngMetadata 2.0) it will use $onInit under the hood, which was introduced in angular 1.5
Example:
```
###### Members
- `ngOnInit()`
## OnChanges
Implement this interface to get notified when any data-bound property of your directive changes.
Called whenever one-way (`@Input(<)`) or interpolation (`@Attr()`) bindings are updated.
The `changes` parameter is a hash whose keys (implements `SimpleChange`) are the names of the bound properties that have changed,
and the values are an object of the form `{ currentValue, previousValue, isFirstChange() }`.
> you can use `SimpleChanges`(alias for `{[propName: string]: SimpleChange}`) for annotating `changes` parameter
Use this hook to trigger updates within a component such as cloning the bound value to prevent accidental mutation of the outer value.
`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.
> NOTE: it works with both @Component and @Directive like angular 2 does, angular 1.5 does support onChanges only on component,
so you are safe with ngMetadata ;)
_Example:_
```typescript
import { bootstrap } from 'ng-metadata/platform-browser-dynamic';
import { Component, Input, OnChanges, SimpleChanges } from 'ng-metadata/core';
@Component({
selector: 'my-cmp',
template: `
<p>myProp = {{$ctrl.myProp}}</p>
<p>myAttr = {{$ctrl.myAttr}}</p>
`
})
class MyComponent implements OnChanges {
@Input() myAttr: string;
@Input() myProp: any;
ngOnChanges(changes: SimpleChanges) {
console.log('ngOnChanges - myProp = ' + changes['myProp'].currentValue);
console.log('ngOnChanges - myAttr = ' + changes['myAttr'].currentValue);
}
}
@Component({
selector: 'app',
template: `
<button ng-click="value = value + 1">Change MyComponent</button>
<button ng-click="str = str + 'world'">Change MyComponent attr</button>
<my-cmp [my-prop]="$ctrl.value" my-attr="{{$ctrl.str}}"></my-cmp>
`,
directives: [MyComponent]
})
export class AppComponent {
value = 0;
str = 'hello';
}
bootstrap( AppComponent );
Members
ngOnChanges(changes: {[propName: string]: SimpleChange})
DoCheck
Implement this interface to get custom granular change detection observations. We can use the DoCheck hook to detect and act upon changes that Angular doesn't catch on its own.
ngDoCheck
gets called to check the changes in the directives.
The default change detection algorithm looks for differences by comparing bound-property values
by reference across change detection runs. When DoCheck
is implemented it can be 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 ( but we don't recommend to use this in production, unless you know what you are doing).
Note:
- The
ngDoCheck
hook is called with enormous frequency — after every change detection cycle no matter where the change occurred (by change detection cycle we mean $digest loop in terms of Angular 1 ). - Most of these initial checks are triggered by Angular's first rendering of unrelated data elsewhere on the page. Mere mousing into another input box triggers a call. Relatively few calls reveal actual changes to pertinent data. Clearly our implementation must be very lightweight or the user experience may suffer.
- directive should not implement both
DoCheck
andOnChanges
at the same time.
// @TODO Differs services are not implemented yet, instead use custom changes handling like shown here
Use KeyValueDiffers
and IterableDiffers
to add your custom check mechanisms.
Example:
In the following example ngDoCheck
uses an IterableDiffers
to detect the updates to the array list
:
import { Component, Input, DoCheck, IterableDiffers } from 'ng-metadata/core';
@Component({
selector: 'custom-check',
template: `
<p>Changes:</p>
<ul>
<li ng-repeat="line in $ctrl.logs">{{line}}</li>
</ul>`
})
class CustomCheckComponent implements DoCheck {
@Input() list: any[];
differ: any;
logs = [];
constructor(differs: IterableDiffers) {
this.differ = differs.find([]).create(null);
}
ngDoCheck() {
const 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 ng-click="$ctrl.list.push($ctrl.list.length)">Push</button>
<button ng-click="$ctrl.list.pop()">Pop</button>
<custom-check [list]="$ctrl.list"></custom-check>`,
directives: [ CustomCheckComponent ]
})
export class AppComponent {
list = [];
}
Members
ngDoCheck()
AfterViewInit
Use this hook only with @Component()
Implement this interface to get notified when your component's view and content is fully initialized.
ngAfterViewInit
is called after all component's content children and view children have been resolved and rendered.
It is invoked every time when the directive is instantiated.
In angular 1 terms, this method is invoked from postLink
Note:
when
@Query
decorators are used, you can be 100% sure that during this life cycle all queried instances/jqElements which are not transcluded(behind ng-if or ng-repeat) will be resolved If you wanna query results from repeater or dynamically, implementAfterViewChecked
to get notifications ans updated instance properties
Example:
```
###### Members
- `ngAfterViewInit()`
## AfterViewChecked
Implement this interface to get notified after every check of your component's view.
`ngAfterViewChecked` is called after all directive's view children(view==template) have been resolved and rendered.
It is invoked every time when the directive is instantiated/destroyed.
In angular 1 terms, this method is invoked from it's own `postLink` and from childrens's `postLink` and `scope.$on('$destroy')` , to prevent memory leaks
**Note:**
> Implement this interface only on parent component which uses one of `@ViewChild`/`@ViewChildren` decorators
> To get notified you must explicitly `@Inject` your parent component to child, so it knows about it's parent
and calls life cycle hooks properly
_Example:_
```typescript
Members
ngAfterViewChecked()
AfterContentInit
Use this only with @Directive()
Implement this interface to get notified when your directive's content fully initialized.
ngAfterContentInit
is called after all directive's content children have been resolved and rendered.
It is invoked every time when the directive is instantiated.
In angular 1 terms, this method is invoked from postLink
Note:
when
@Query
decorators are used, you can be 100% sure that during this life cycle all queried instances/jqElements which are projected via ng-transclude and which are not dynamicly rendered(with ng-if or ng-repeat) will be resolved If you wanna query results from repeater or dynamically, implementAfterContentChecked
to get notifications ans updated instance properties
Example:
```
###### Members
- `ngAfterContentInit()`
## AfterContentChecked
Implement this interface to get notified after every check of your directive's content.
`ngAfterContentChecked` is called after all directive's content children(content projected via `ng-transclude`) have been resolved and rendered.
It is invoked every time when the directive is instantiated and when content directives are created/destroyed.
In angular 1 terms, this method is invoked from it's own `postLink` and from children's `postLink` and `scope.$on('$destroy')` , to prevent memory leaks
**Note:**
> Implement this interface only on parent component/directive which uses one of `@ContentChild`/`@ContentChildren` decorators
> To get notified you must explicitly `@Inject` your parent component/directive to child, so it know about it's parent
and calls life cycle hooks properly
_Example:_
```typescript
Members
ngAfterContentChecked()
OnDestroy
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(directive) is destroyed.
In angular 1 terms, it's invoked when $scope.$destroy()
is called.
Example:
typescript
Members
ngOnDestroy()