Reputation: 1123
Everywhere it is said that markForCheck just marks current component view and all parent components (up to the root one) as dirty. So next time DetectChanges executes it will update the view.
From this point I have 2 questions. Both in a context that component has changeDetection: ChangeDetectionStrategy.OnPush
1) If 'async pipe' does nothing but call markForCheck (source code), Why the view is updated?
2) If I try calling markForCheck inside some async process, the view will be updated as well.
The demo: stackblitz
Can you help me to understand what happens during these processes and why the view actually updated? I am expecting that someone call DetectChanges method after 1) and 2), but who...
Upvotes: 6
Views: 4426
Reputation: 1123
With help of @David I found the answer.
First things first, RxJs is not wrapped with zone anyhow, but native async functions are (as setTimer/Iterval
, fetch
api, XHR
, DOM events
). Because of RxJs timer/delay(...) operators use native async functions this causes them to be handled in a context of zone as well.
This is how the Callstack looks like when we are in the Rx tap
operator
You can see that Rx part comes after Angular/Zone one.
Angular in his turn uses zone to call tick()
function whenever async callback is executed. Tick
method goes down from root component and looks for marked for checking views.
I put breakpoint in tick function, it is called after our callback is executed
So what happens in the first case when we use async pipe
on the template.
tick()
is called. Which finally will check the view and update itAnd almost the same happens in the second case, when we call markForCheck
inside RxJs operator. We do the same thing as async pipe
does, and because our callback is also wrapped with zone we have the the same process be executed after callback is done.
If you will not call markForCheck in your async callback, but call tick function, no update will be done. Worth mentioning that if you call detectChanges() the update will be done despite not calling markForCheck function. Here is the example on stackblitz This is due to detechChanges from ChangeDetectorRef ignores markForCheck flag and does change detection for Component and all its children. A lot more details in this article
This method runs change detection for the current component view regardless of its state
Upvotes: 3
Reputation: 10979
See at the time of onpush, any changes in inputs make the component dirty and then only re-rendering is done. But if you want to make it dirty even without these events you can call markDirty method for changeDetection to happen. Please find the link to official statement below :-
Upvotes: 0