I have a Plunkr demoing the problem here: https://plnkr.co/edit/e5OVhuWtyStxI1vvXd9h
Summary is:
I have a Parent and Child component. Child has change detection strategy set to onPush.
Child's template is just this:
@Component({
selector: 'child',
template: `
<button (click)="changeHello()">Change</button>
{{hello}}
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent {
hello = "hi";
ngOnChanges() {
console.log("on changes called");
}
ngDoCheck() {
console.log("do check called");
}
changeHello() {
this.hello = "goodbye";
}
}
Why when I click the button everything works and the change actually reflected in the view? (i.e. change from hi
to goodbye
)
I thought the order of events would be:
- User clicks button
- The "hello" class property now points to the "goodbye" string
onTurnDone()
zone event is invoked and Angular starts performing change detection from the root- When on the root, it notices that none of the Child inputs have changed, and because its Change Detection strategy is set to onPush, it stops there and does not run change detection in the child
- The
{{hello}}
in the template is not updated togoodbye
and still displays the oldhi
Where have I gone wrong with my above reasoning?
Why does ngDoCheck()
get called?