В этой статье я собираюсь объяснить хуки жизненного цикла в angular — тему, которую должен знать каждый разработчик Angular.

1)Нгонинт

Это вызывается после того, как angular создает экземпляр вашего компонента через конструктор, другими словами, он вызывается angular, чтобы указать, что angular создает компонент. Это первый хук, который вызывается angular, если в вашем компоненте нет свойств @Input, и он вызывается только один раз.

UseCase: вы можете писать все вызовы API внутри NgonInit.

2) NgOnChange

Он вызывается перед NgOnInit, если есть какие-либо изменения свойств @Input, и он будет вызываться несколько раз, если есть несколько изменений @Input. Если в вашем компоненте нет свойств @Input, то этот хук будет пропущен angular

UseCase: если вы хотите выполнить какую-либо операцию на основе изменений свойств @Input, вы можете сделать это в NgOnChange. У NgOnChange есть аргумент simpleChanges, который полезен для просмотра текущих и предыдущих значений входных свойств.

Вот пример NgOnChange с аргументом SimpleChange.

export class MyComponent implements OnInit, OnChanges {

  @Input() myValProp: string;

  constructor() { }

  ngOnInit() {}

  ngOnChanges(changes: SimpleChanges) {
      console.log(changes.myValProp.currentValue); // latestValue
      console.log(changes.myValProp.firstChange);  // false(If it is not a first change)
      console.log(changes.myValProp.previousValue  // oldValue 
    );
  }
}

3)НгДоПроверить

Он вызывается всякий раз, когда запускается вывод сдачи, и сразу после NgOnInt и NgOnChange.

UseCase:алгоритм вывода угловых изменений по умолчанию ищет разницу, сравнивая свойства @Input по ссылке из-за этого поведения по умолчанию. NgOnchange не сможет вычесть изменения, если кто-то изменит свойство объекта на попробуйте добавить новый элемент в массив через Ngonchange, мы сможем поймать эти изменения

Вот пример NgDoCheck

@Component({
  selector: 'app-parent',
  template: `<a (click)="updateUser()">UpdateUser</a><br/>
              <app-child [user]="user"></app-child>`
})
export class ParentComponent implements OnInit {
  user = {
    name:"medium"
  }
  updateUser(){
    this.user.name = "google"
  }
}

/* Child component */
@Component({
  selector: 'app-child',
  template: `Here is the user name: {{ user.name }}`
})
export class ChildComponent implements OnInit {
  @Input() user;
  oldUser: string;

  constructor(private cd: ChangeDetectorRef){}

  ngOnInit() {}

  ngOnChanges(changes: SimpleChanges) {
  // User property changes won't be reflected here 
  }

  ngDoCheck() {
    if (this.oldUser !== this.user.name) {
        this.oldUser= this.user.name; // Latest user property is updated here
        this.cd.detectChanges();  // Running change deduction 
    }
  }
}

4)NgAfterContentInit

Это вызывается сразу после того, как angular завершил инициализацию всего содержимого компонента, он вызывается только один раз. Здесь контент означает, что вы можете вводить или проецировать некоторые динамические элементы HTML из компонента «родитель-потомок», используя проекцию контента.

UseCase: если вы хотите получить доступ к элементу dom проекции контента, вы можете сделать это здесь.

Вот пример NgAfterContentInit

@Component({
  selector: 'my-app',
  template: `<hello>
     <div #child>test</div>   --> here we passing div as content     
    </hello>`,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
}

@Component({
  selector: 'hello',
  template: `<ng-content></ng-content>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent{

 @ContentChild('child') contentChild;

 ngAfterContentInit(){
   console.log("Child Content init", this.contentChild);
 }
}

5)NgAfterContentChecked

Это будет вызвано, если будут какие-либо изменения с содержимым компонента. В отличие от NgAfterContentInit, этот хук срабатывает каждый раз, когда содержимое обновляется.

UseCase: если вам нужно написать какую-то логику с последним контентом, используйте этот хук.

Вот пример NgAfterContentChecked( Если нажата кнопка click me, свойство ввода имени изменяется для компонента имени, который динамически проецируется на компонент приветствия, поскольку это приводит к некоторому изменению содержимого, поэтому Будет запущен хук NgAfterContentChecked)

@Component({
  selector: 'my-app',
  template: `<hello> 
      <name-component [name]="name"></name-component>    
      </hello>
      <button(click)="changeName();">Click me</button>`
    })
export class AppComponent  {
name = "hello world"

changeName() {
 this.name = "name Changed"
}
}

@Component({
  selector: 'hello',
  template: `<h1>{{name}}</h1>
  <ng-content></ng-content>`,
})
export class HelloComponent{

 ngAfterContentChecked(){
   console.log("Child Content checked is triggred");
 }
}

6)NgAfterViewInit

Он вызывается, когда компонент и его дочернее представление полностью инициализированы.

UseCase: вы можете получить доступ к компоненту или его дочернему элементу dom под этим хуком.

Вот пример NgAfterViewInit

/*Html */
<p #pRef>
  Hello world
</p>

export class AppComponent implements AfterViewInit, OnInit {

  @ViewChild('pRef', {static: false}) pRef: ElementRef;
    ngAfterViewInit() {
      console.log(this.pRef.nativeElement.innerHTML);  // Hello World
      this.pRef.nativeElement.innerHTML = "DOM is updated succesfully"
    }
    ngOnInit() {
      /*this.pRef.nativeElement.innerHTML = "DOM updated succesfully!!!"; */ 
      // Here you can't access the viewchild
    }
}

7)NgAfterViewChecked

Он вызывается всякий раз, когда angular завершает выполнение вывода изменений для компонента и его дочернего компонента. Таким образом, angular вызовет этот хук, если компонент или его дочерний вид будут обновлены.

UseCase: если вы хотите выполнить какую-либо операцию после того, как компонент и его дочерние элементы были инициализированы и проверены (после вычета изменений)

8)NgOnDestroy

Это будет вызвано, если компонент больше не требуется в Доме.

UseCase: вы можете использовать этот хук для целей очистки, таких как отмена подписки на все ваши подписки.

Вот пример NgOnDestroy

destroy$: Subject<> = new Subject<>();

ngOnInit() {
  of(1,2,3,4,5)
    .pipe(takeUntil(this.destroy$))
    .subscribe(v => {})
}
ngOnDestroy() {
  this.destroy$.next()
  this.destroy$.complete();
}