Sebastien Vasylets

junior Frontend Developer in Artcom Venture

@SebastienV - telegram

@shoulddomore - twitter

Change Detection in Depth

Обнаружение изменений -

что это и зачем

App

C2

B2

B1

A1

D1

C1

App

C2

B2

B1

A1

D1

C1

C2

B2

D1

C1

Инициализация приложения проходит в два этапа:

  1. ​выстраивается дерево компонентов

  2. запустить обнаружение изменений компонентов

Все lifecycle hooks будут применены, как часть  обнаружения изменений

Зачем constructor(){} :

  1. инит всех зависимости
  2. constructor injection pattern

Зачем ngOnInit(){} :

  1. обозначает, что закончено построение DOM'a
  2. прошёл инжект всех зависимостей в конструкторе
  3. проставлены байдинги свойств между компонентом
// some code

@Component({
  selector: 'component-one',
  templateUrl: './component-one.html',
  styleUrls: ['./component-one.css'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
// some code

@Component({
  selector: 'component-two',
  templateUrl: './component-two.html',
  styleUrls: ['./component-two.css'],
  // ChangeDetectionStrategy.Default - это дефолтное значение,
  // оно сетить в Default, если не указано обратного
  changeDetection: ChangeDetectionStrategy.Default
})

ChangeDetectionStrategy.Default

ChangeDetectionStrategy.OnPush

Итоги:

  •   Angular приложение - это дерево компонентов

  • Каждый компонент обладает своей view

  • *Обновление view компонента обновляет его чаилдов

1 view = 1 component

1 component = 1 view

@Component({
  selector: 'parent',
  template: `
    <child-one></child-one>
    <child-two></child-two>
  `
})

export class ParentComponent {

// some code

}
@Component({
  selector: 'child-one',
  template: `
    <p>lorem ipsum dolor sit amet</p>
    <child-three></child-three>
  `
})

export class ChildOneComponent {

// some code

}

  ViewState of component:

  • FirstCheck

  • *ChecksEnabled

  • Errored

  • Destroyed

*ViewState.ChecksEnabled = false;

checkAndUpdateView()

  1. обновляет входящие свойства у экземпляров дочерних компонентов

  2. обновляет состояние обнаружения изменений у дочерних view

  3. вызывает на дочерних компонентах хук OnChanges

  4. вызывает хуки OnInit и ngDoCheck на дочерних компонентах

  5. вызывает хуки AfterContentInit, AfterContentChecked, AfterViewInit и AfterViewChecked на экземплярах дочерних компонентов

  6. вызывает хук OnDestroy, если дочерний/родительский компонент удален

  7. обновляет DOM для текущего view

  8. запускает обнаружение изменений для дочерних view

  9. отменяет проверки изменений для текущего view

  10. устанавливает значение false для флага состояния FirstCheck

class ChangeDetectorRef {
  markForCheck(): void
  detach(): void
  detectChanges(): void
  checkNoChanges(): void
  reattach(): void
}

Angular позводяет нам управлять изменением состоянием view через интерфейсы этого класса ChangeDetectorRef

ChangeDetectorRef.detectChanges()
import {
  Component, Input,ChangeDetectionStrategy, ChangeDetectorRef
} from '@angular/core';

@Component({
  selector: 'child-component',
  template: `
    <div class="footer">
      <button (click)="refresh()"</button>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
  // ^ ограничиваем обнаружение изменений
})
export class ChildComponent {
  @Input() someData: any;

  constructor(
    private _cd: ChangeDetectorRef
  ) {}

  refresh() {
    this._cd.detectChanges();
    // принудительно запускаем проверку 
    // обнаружение изменений компонента
  }
}
ChangeDetectorRef.markForCheck()
let obj = {
  name: 'Bruce',
  lastname: 'Wayne'
}


obj.lastname = 'Willis';


obj = {
  name:"Lee"
};

ChangeDetectorRef.detach()
@Component({
  selector: 'b2',
  template: `
    <c1></c1>
    <c2></c2>
  `
})

export class B2 {

  constructor(public _cd: ChangeDetectorRef) {
    this._cd.detach();
  }

}

App

C2

B2

B1

A1

D1

C1

ChangeDetectorRef.reattach()
ChangeDetectorRef.checkNoChanges()

Change Detection in Depth

By Sebastien Vasylets (SebastienV)

Change Detection in Depth

Slides for Angular Meetup Kyiv #4 by Sebastien Vasylets about Change Detection in Angular

  • 1,078