Оглавление:
Карта сайта:
Оглавление:
Карта сайта:
<database pages>
После создания компонента фреймворк Angular вызывает у этого компонента ряд методов, которые представляют различные этапы жизненного цикла:
Каждый такой метод определен в отдельном интерфейсе, который называется по имени метода без префикса «ng». Например, метод ngOnInit определен в интерфейсе OnInit. Поэтому, если мы хотим отслеживать какие-то этапы жизненного цикла компонента, то класс компонента должен применять соответствующие интерфейсы:
import { Component, OnInit, OnDestroy } from '@angular/core'; @Component({ selector: 'my-app', template: `<p>Hello Angular 2</p>` }) export class AppComponent implements OnInit, OnDestroy { name:string="Tom"; constructor(){ this.log(`constructor`); } ngOnInit() { this.log(`onInit`); } ngOnDestroy() { this.log(`onDestroy`); } private log(msg: string) { console.log(msg); } }
Метод ngOnInit() применяется для какой-то комплексной инициализации компонента. Здесь можно выполнять загрузку данных с сервера или из других источников данных.
ngOnInit() не аналогичен конструктору. Конструктор также может выполнять некоторую инициализацию объекта, в то же время что-то сложное в конструкторе делать не рекомендуется. Конструктор должен быть по возможности простым и выполнять самую базовую инициализацию. Что-то более сложное, например, загрузку данных с сервера, которая может занять продолжительное время, лучше делать в методе ngOnInit.
Метод ngOnDestroy() вызывается перед удалением компонента. И в этом методе можно освобождать те используемые ресурсы, которые не удаляются автоматически сборщиком мусора. Здесь также можно удалять подписку на какие-то события элементов DOM, останавливать таймеры и т.д.
Метод ngOnChanges() вызывается перед методом ngOnInit() и при изменении свойств в привязке. С помощью параметра SimpleChanges в методе можно получить текущее и предыдущее значение измененного свойства. Например, пусть у нас будет следующий дочерний компонент:
import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core'; @Component({ selector: 'child-comp', template: `<p>Привет {{name}}</p>` }) export class ChildComponent implements OnInit, OnChanges { @Input() name: string; constructor(){ this.log(`constructor`); } ngOnInit() { this.log(`onInit`); } ngOnChanges(changes: SimpleChanges) { for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); this.log(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); } } private log(msg: string) { console.log(msg); } }
И пусть этот компонент используется в главном компоненте:
import { Component, OnChanges, SimpleChanges} from '@angular/core'; @Component({ selector: 'my-app', template: `<child-comp [name]="name"></child-comp> <input type="text" [(ngModel)]="name" /> <input type="number" [(ngModel)]="age" />` }) export class AppComponent implements OnChanges { name:string="Tom"; age:number = 25; ngOnChanges(changes: SimpleChanges) { for (let propName in changes) { let chng = changes[propName]; let cur = JSON.stringify(chng.currentValue); let prev = JSON.stringify(chng.previousValue); this.log(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); } } private log(msg: string) { console.log(msg); } }
То есть значение для свойства name передается в дочерний компонент ChildComponent из главного - AppComponent. Причем в главном компоненте тоже реализован метод ngOnChanges().
И если мы запустим приложение, то сможем заметить, что при каждом изменении свойства name в главном компоненте вызывается метод ngOnChanges:
В то же время надо отметить, что данный метод вызывается только при изменении входных свойств с декоратором @Input. Поэтому изменение свойства age в AppComponent здесь не будет отслеживаться.
Определим следующий дочерний компонент:
import { Component, Input, OnInit, DoCheck, OnChanges, AfterContentInit, AfterContentChecked, AfterViewChecked, AfterViewInit} from '@angular/core'; @Component({ selector: 'child-comp', template: `<p>Привет {{name}}</p>` }) export class ChildComponent implements OnInit, DoCheck, OnChanges, AfterContentInit, AfterContentChecked, AfterViewChecked, AfterViewInit { @Input() name: string; count:number=1; ngOnInit() { this.log(`ngOnInit`); } ngOnChanges() { this.log(`OnChanges`); } ngDoCheck() { this.log(`ngDoCheck`); } ngAfterViewInit() { this.log(`ngAfterViewInit`); } ngAfterViewChecked() { this.log(`ngAfterViewChecked`); } ngAfterContentInit() { this.log(`ngAfterContentInit`); } ngAfterContentChecked() { this.log(`ngAfterContentChecked`); } private log(msg: string) { console.log(this.count + ". " + msg); this.count++; } }
И используем этот компонент в главном компоненте:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<child-comp [name]="name"></child-comp> <input type="text" [(ngModel)]="name" />` }) export class AppComponent{ name:string="Tom"; }
И при обращении к приложению мы получим следующую цепочку вызовов:
</pages>