Search code examples
angularangular2-changedetection

Angular change detection: why is entire tree checked on local changes?


Let's say I have a simple array of texts:

textContent = [
    {text: 'good morning'},
    {text: 'lovely day'},
    {text: 'for debugging'},
  ]

I render a simple component for each, passing in the text item as input:

<app-text *ngFor="let text of textContent" [text]="text"></app-text>

The text component renders the text, with ngModel:

<textarea [(ngModel)]="text.text"></textarea>

I'm also logging on DoCheck:

ngDoCheck() {
    console.log(this.text.text, ' has been checked')
}

When I enter something into one textarea, all other components' DoCheck is fired.

good morning   has been checked
lovely days    has been checked
for debuggings has been checked

This happens even when OnPush is used for change detection.

Question: Why do changes made to one component's data trigger the entire tree to be checked?

(It's not a problem with a handful of components, but with a larger tree, I'm dropping frames).

I actually noticed that even components on a completely separate content tree have their 'doCheck' also fired.

Is there a way to prevent this from happening, or am I missing something else entirely?


Solution

  • My question was based on a misunderstanding on my part, so let me clarify:

    When a component's DoCheck() lifecycle hook is called, this does not mean that it has been change detected. It only means that Angular is doing a change detection run, and is giving you the opportunity hook into it, to execute some custom logic.

    This article If you think ngDoCheck means your component is being checked — read this article has more details.