'Angular 5 - how to limit change detection only to component scope?
How to configure Angular component not to trigger change detection for the whole application but only for the component itself and his children?
Working example: https://stackblitz.com/edit/angular-irc-starter-4txpbu?file=app%2Ftimer%2Ftimer.component.ts
There is a counter that increases value by one every second. It's TimerComponent and it's working as intended - value is increased and updated every second.
@Component({
selector: 'app-timer',
template: `{{value}}`
})
export class TimerComponent implements OnInit {
value: number = 0;
ngOnInit() {
setInterval(() => this.value++, 1000);
}
}
However, look at the parent component AppComponent.
<h3>Internal timer:</h3>
<p>Should not perform change detection for the whole app</p>
<app-timer></app-timer>
<h3>External binding</h3>
<p>Should not be updated after timer changes</p>
<p>{{someBindingProperty}}</p>
someBindingProperty is a getter:
get someBindingProperty() {
this.bindingTimer++;
return this.bindingTimer;
}
The problem: when TimerComponent increases value, change detection is triggered for the whole application. Is it possible to trigger change detection only within the component and children?
Note: if I add to TimerComponent:
changeDetection: ChangeDetectionStrategy.OnPush
Then changes are not detected within this component but change detection is still triggered for the whole application. So this is not a solution.
Solution 1:[1]
Another option to temporary disable change detection ChangeDetectorRef
enabled = true;
constructor(private ref: ChangeDetectorRef)
toggleChangeDetection() {
if (this.enabled)
{
this.enabled = false;
this.ref.detach();
}
else {
this.enabled = true;
this.ref.reattach();
}
Solution 2:[2]
You can run the interval for you timer outside of the angular zone and call ChangeDetectorRef.detectChanges
everytime the timer value increases:
this.ngZone.runOutsideAngular(() => {
setInterval(() => {
this.timer++;
this.cdr.detectChanges();
}, 1000);
});
ChangeDetectorRef.detectChanges
only detects changes for this view and its children.
I tried it out and using the Angular DevTools profiler you can see that neither the root component (AppComponent), nor the sibling component (SthWithDefaultCdComponent) got checked. Whether the timer component uses OnPush strategy or not does not make a difference.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | parag badala |
Solution 2 | slim |