Issue
I have been working on a project and I have seen people use change detector.
cdRef.detectChanges()
I am a little confused as to when to explicitly use this to mark that the component has changed. When should we leave it up to angular? Or am I missing something here?
Solution
Basically there is something called change-detection tree: it collects all the views that are checked for changes.
ChangeDetectorRef allows you to manipulate this tree, angular runs the change detection every time there is a change. For example, when you have a large amount of data and there is a change in that data, angular will render the view again, if the data changes every second, your application will become slower.
One thing you could do is; detach the view from the tree with ref.detach()
(Detaches this view from the change-detection tree), so you can decide when to update the view, and for that you use ref.detectChanges()
to locally detect the changes in your component.
There is also something called ChangeDetectionStrategy
, this comes in play when you have @Inputs in your component. If you use changeDetection: ChangeDetectionStrategy.OnPush
in your component , angular will only check once.
Use the CheckOnce strategy, meaning that automatic change detection is deactivated until reactivated by setting the strategy to Default (CheckAlways). Change detection can still be explicitly invoked. This strategy applies to all child directives and cannot be overridden.
Using this, angular obliges us to work with immutable objects, so if you want to update the view you must pass a new object to your @Input. But, what happens if you have a internal state that you want to update every time you click a button, well….it will not work unless you explicitly invoke the change detection.
So you could try ref.detectChanges()
to run change detection on the component and his children or ref.markForCheck()
which does not trigger change detection and instead it will mark all onPush ancestors as to be checked once.