In-depth knowledge of change detection mechanism in Angular views

In-depth knowledge of change detection mechanism in Angular views

This is the original source for your reference. https://hackernoon.com/everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f

Below it is the main change detection procedure:

Angular has a bunch of high-level concepts to manipulate the views. I’ve written about some of them here. One such concept is ViewRef. It encapsulates the underlying component view and has an aptly named method detectChanges. When an asynchronous event takes place, Angular triggers change detection on its top-most ViewRef, which after running change detection for itself runs change detection for its child views.

The main logic responsible for running change detection for a view resides in checkAndUpdateView function. Most of its functionality performs operations on child component views. When it’s triggered for a particular view it does the following operations in the specified order:

  1. updates input properties on a child component instance
  2. updates child view change detection state (part of change detection strategy implementation)
  3. calls OnChanges lifecycle hook on a child component if bindings changed
  4. calls OnInit and ngDoCheck on a child component
  5. calls AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked lifecycle hooks on child component instance
  6. calls OnDestroy if the child/parent component is destroyed
  7. updates DOM for the current view if properties on current viewcomponent instance changed
  8. runs change detection for a child view
  9. disables checks for the current view (part of change detection strategy implementation)
  10. sets FirstCheck to false

There are few things to highlight based on the operations listed above.

The first thing is that onChanges lifecycle hook is triggered on a child component before the child view is checked and it will be triggered even if changed detection for the child view will be skipped. This is important information and we will see how we can leverage this knowledge in the second part of the article.

The second thing is that DOM for a view is updated as part of a change detection mechanism while the view being checked. This means that if a component is not checked, the DOM is not updated even if component properties used in a template change.

And the way to interfere Angular’s change detection procedure on particular views( components) can be done through DI of ChangeDetectorRef on that component:

class ChangeDetectorRef {
  markForCheck() : void
  detach() : void
  reattach() : void
  
  detectChanges() : void
  checkNoChanges() : void
}
export class AComponent {
  constructor(public cd: ChangeDetectorRef) {
    this.cd.detach();
  }

@Component({
  selector: 'a-comp',
  template: `<span>See if I change: {{changed}}</span>`
})
export class AComponent {
  constructor(public cd: ChangeDetectorRef) {
    this.changed = 'false';

    setTimeout(() => {
      this.cd.detach();
      this.changed = 'true';
    }, 2000);
  }


let currView: ViewData|null = view;
while (currView) {
  if (currView.def.flags & ViewFlags.OnPush) {
    currView.state |= ViewState.ChecksEnabled;
  }
  currView = currView.viewContainerParent || currView.parent;
}

export class AComponent {
  @Input() inputAProp;

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

  ngOnChanges(values) {
    this.cd.detectChanges();
  }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.