Perhaps I'm missing something in Change Detection mechanism in Angular.
I have 2 components:
AppComponent.
@Component({
selector: 'my-app',
template: `
<button
(click)="0">
Async Action in Parent
</button>
<child
[config]="config">
</child>
<button
(click)="mutate()">
Mutate Input Object
</button>
`
})
export class AppComponent {
config = {
state: 0
};
mutate() {
this.config.state = 1;
console.log(this.config.state);
}
}
and ChildComponent
@Component({
selector: "child",
template: `
<h1>{{config.state}}</h1>
<button
(click)="0">
Async Action in Child
</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent {
@Input() config;
ngDoCheck() {
console.log(`Check`);
}
}
Step 1.
Here, on clicking a button from AppComponent
I invoke mutate
function which in turn mutates the object which is passed to a nested ChildComponent
.
Step 2.
Then I click the other button from the same AppComponent
just in order to trigger Change Detection cycle. Since ChildComponent
is using OnPush
strategy and input reference didn't change then during the following Change Detection ChildComponent
's view is not checked and DOM interpolations are not updated. And up to this point it behaves as I expect it.
But if on Step 2. I trigger Change Detection from within ChildComponent
(by clicking appropriate button) then ChildComponent
's view is checked and DOM interpolations are updated. Why is it so? Nothing has changed since the previous time.
Here is the demo on StackBlitz.
I've read a great article on Change Detection by Maxim Koretskyi but unfortunately it didn't answer my question.