31
Июл
2019

Жизненный цикл компонента

Каждый компонент имеет свой жизненный цикл (Component Lifecycle), в процессе которого вызываются ряд описывающих текущий этап методов (Angular Hooks):

  • OnChanges – устанавливаются или изменяются значения входных свойств класса компонента;
  • OnInit – устанавливаются “обычные” свойства; вызывается единожды вслед за первым вызовом OnChanges();
  • DoCheck – происходит изменения свойства или вызывается какое-либо событие;
  • AfterContentInit – в шаблон включается контент, заключенный между тегами компонента;
  • AfterContentChecked – аналогичен DoCheck(), только используется для контента, заключенного между тегами компонента;
  • AfterViewInit – инициализируются компоненты, которые входят в шаблон текущего компонента;
  • AfterViewChecked – аналогичен DoCheck(), только используется для дочерних компонентов;
  • OnDestroy – компонент “умирает”, т.е. удаляется из DOM-дерева

В списке выше все методы перечислены в порядке их вызова.

Angular hooks реализованы в виде интерфейсов, реализующих функцию, совпадающую по названию с названием интерфейса + префикс ng.(untitled)


    export class ContactsItemComponent implements OnInit {
      ...
      ngOnInit() {
        console.log('OnInit');
      }
        ...
     }
    

Чтобы стало понятно, разберем пример.hooks-example.component.ts


    @Component({
     selector: 'hooks-example',
     template: `
       <contacts-list [title] = '"Managers"'>
         <contacts-item [name] = '"Peter"'></contacts-item>
       </contacts-list>
     `
    })
    export class HooksExampleComponent{}
    

contacts-list.component.ts


    @Component({
     selector: 'contacts-list',
     template: `
       <h2>Contacts List of {{company}}</h2>
       <ng-content></ng-content>
       <contacts-item [name] = '"Jack"'></contacts-item>
       <contacts-item [name] = '"Daniel"'></contacts-item>
     `
    })
    
    export class ContactsListComponent implements OnChanges, OnInit, DoCheck, AfterContentInit,
     AfterContentChecked, AfterViewInit, AfterViewChecked{
    
    @Input() title: string;
    
    company: string = 'Google Inc.';
    
     @ViewChild(ContactsItemComponent) vwCh: ContactsItemComponent;
     @ContentChild(ContactsItemComponent) cntCh: ContactsItemComponent;
    
     ngOnChanges(obj: SimpleChanges){
       console.log('OnChanges', obj);
     }
    
     ngOnInit(){
       console.log('OnInit', this.company);
     }
    
     ngDoCheck(){
       console.log('DoCheck');
     }
    
     ngAfterContentInit(){
       console.log('AfterContentInit', this.cntCh);
     }
    
     ngAfterContentChecked(){
       console.log('AfterContentChecked');
     }
    
     ngAfterViewInit(){
       console.log('AfterViewInit', this.vwCh);
     }
    
     ngAfterViewChecked(){
       console.log('AfterViewChecked');
     }
    }
    

contacts-item.component.ts


    @Component({
     selector: 'contacts-item',
     template: `<p>{{name}}</p>`
    })
    
    export class ContactsItemComponent {
     @Input() name: string = null;
    }
    

Запустите приложение c открытой консолью браузера. На примере Component Lifecycle выглядит так:

Первым вызывается OnChanges(), повторный вызов которого осуществляется при изменении хотя бы одного входного свойства. В качестве аргумента ему передается объект с текущим и предыдущим значениями измененных @Input() свойств.

Если входные свойства отсутствуют, то метод не будет вызван.

Следом вызывается OnInit(), который говорит о том, что инициализированы внутренние свойства компонента, в данном случае свойство company. Метод вызывается только один раз.

Третьим по счету идет DoCheck(), который отслеживает изменения, не связанные со свойствами. Его вызов осуществляется довольно часто, в ответ на каждое взаимодействие пользователя с интерфейсом (например, фокусировка поля формы или потеря фокуса).

Далее инициализируются шаблоны. Сначала подгружается контент, находящийся между тегами компонента. За это отвечает ngAfterContentInit().

Для отображения переданного контента в представлении компонента используется парный тег <ng-content></ng-content>.

На этом этапе Component Lifecycle можно получить переданный извне компонент. Для этого используется декоратор @ContentChild(), который в качестве аргумента принимает название компонента, также рекомендуется указывать его тип. Передавать можно не только компонент, но и обычный HTML, доступ к которому осуществляется через ссылку на него, подробно здесь.(untitled)


    @ContentChild(ContactsItemComponent) contentChild: ContactsItemComponent;
    

Следующим при любых изменениях во внешнем шаблоне вызывается ngAfterContentChecked().

Если вам нужно получить все экземпляры указанного компонента, используйте декоратор @ContentChildren().

Методы ngAfterViewInit() и ngAfterViewChecked() схожи с ngAfterContentInit() и ngAfterContentChecked() лишь с тем различием, что первые два вызываются после полной иницализации шаблона.

Используя декораторы @ViewChild() и @ViewChildren() можно получить доступ к прямым дочерним компонентам.

Как и сами Angular Hooks, декораторы находятся в библиотеке @angular/core.

Чтобы инициировать вызов OnDestroy(), необходимо удалить компонент из DOM-дерева (переход на другой URL или с помощью *ngIf).

Share

Тебе может это понравится...