3

I am using the OnPush strategy and according to this article if no inputs change, there is no need to check the component’s template. But in my example when I am clicking the trigger button and the inputs does not change in this case the ngAfterViewChecked hook still running. What am I missing?

import {Component, NgModule, Input, ChangeDetectionStrategy} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'cmp',
  template: `
    <h1>{{data.name}}</h1>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class Cmp {
  @Input() data;

  ngOnChanges() {
    console.log('ngOnChanges');
  }

  ngAfterViewChecked() {
    console.log('view checked');
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <cmp [data]="data"></cmp>
      <button (click)="trigger()">trigger</button>
      <button (click)="change()">Change</button>
    </div>
  `,
})
export class App {
  constructor() {
    this.data = {
      name: 'Angular'
    }
  }

  trigger() {

  }

  change() {
    this.data = {
      name: 'Angular2'
    };
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, Cmp ],
  bootstrap: [ App ]
})
export class AppModule {}
1

1 Answer 1

2

You're not missing anything. Your expectations about ngAfterViewChecked are right and it's not called for subtree components when the parent changeDetectionStrategy is OnPush.

There is currently an issue opened on Github and it seems that triggering the lifecycle callback is not the only problem because some checks are actually made.

Sign up to request clarification or add additional context in comments.

2 Comments

It's called on the Cmp and it shouldn't.
Yes it shouldn't for Cmp. This is actually a reported bug, but I clarified that it doesn't happen for subtree components.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.