AngularJS life cycle Hooks. Teil 2: $onInit
Update: 25.05.2016 - Das Verhalten des $onChanges-Hooks hat sich mit der 1.5.5 Version geändert.
$onInit
Wie schon im ersten Teil der Serie erwähnt, ist der $onInit-Hook der erster Hook der aufgerufen wird. Seit Angular 1.5.5 ist der $onChanges-Hook der erste Hook der aufgerufen wird. Dadurch ist dieser der idealer Ort, um initialisierungs Code für die Komponente auszuführen. Wir können z. B. Standartwerte für das Modell definieren oder Serveranfragen starten, um Daten zu holen. Hier ein kleines Beispiel:
function controllerFn() {
this.$onInit = function() {
this.data = 'New Data!';
};
}
var component = {
template: '<p>{{$ctrl.data}}</p>',
controller: controllerFn
};
angular.module('app', [])
.component('myApp', component);
Natürlich können wir auch initialisierungs Code in der Konstruktorfunktion haben. Aber die Bindings sprich Daten, die die Parent-Komponente der Child-Komponente übergibt stehen dem Konstruktor nicht zur Verfügung. Wenn wir also Daten von den Bindings für die Initialisierung brauchen, müssen wir die Initialisierung in dem $onInit-Hook durchführen. Hier ein Beispiel:
function parentCtrl() {
this.number = 2;
}
var parentComponent = {
template: '<p>Parent</p><child-component num="$ctrl.number"></child-component>',
controller: parentCtrl
};
function childCtrl() {
this.$onInit = function() {
this.timesTwo = this.num * 2;
};
}
var childComponent = {
template: '<p>Child: {{$ctrl.timesTwo}}</p>',
controller: childCtrl,
bindings: {
num: '<'
}
};
angular.module('app', [])
.component('myApp', parentComponent)
.component('childComponent', childComponent);
In diesem Beispiel bekommt die Child-Komponente eine Zahl, die mit zwei multipliziert wird bevor diese angezeigt wird. Die Zahl wird in der Konstruktorfunktion der Parent-Komponente definiert und mittels ein-Weg-Datenbindung der Child-Komponente übergeben. Da wir mit einer Bindung arbeiten, können wir die Multiplikation nicht in der Konstruktorfunktion der Child-Komponente durchführen. Die num-Eigenschaft ist dort noch nicht definiert. Wir müssen dafür den $onInit-Hook nutzen. Allerdings hätten wir in diesem trivialen Beispiel die Multiplikation auch im Template definieren können.
Auch die Controller von Direktiven/Komponenten, die in der require-Eigenschaft referenziert werden, stehen der Konstruktorfunktion nicht zur Verfügung. Wenn wir also bei der Initialisierung mit so einem Controller interagieren möchten, muss diese Interaktion im $onInit-Hook stattfinden.
Fazit
Der $onInit-Hook ist der erster Hook der von Angular aufgerufen wird. Seit 1.5.5 ist $onInit der zweite Hook der aufgerufen wird. Dieser ist hilfreich, wenn wir bei der Initialisierung einer Komponente mit externe Controllers oder mit Bindings interagieren müssen.