I have a large ponent, and I would like to avoid unnecessary change detections to increase performance.
I added changeDetection: ChangeDetectionStrategy.OnPush
to the @Component
.
I would like to update the style of an element if it is scrolled. Unfortunately Angular runs the change detection, every time I scroll that element.
I tried to add an event listener to the native element to avoid this, but the change detection is still running again when I scroll:
@ViewChild('my_element') my_element_ref: ElementRef;
ngOnInit() {
this.my_element_ref.nativeElement.addEventListener('scroll', this.updateStyle);
}
ngAfterViewChecked() {
console.log('check');
}
The ngAfterViewChecked
is called even if this.updateStyle
is an empty function.
But if I ment out this.my_element_ref.nativeElement.addEventListener('scroll', this.onScroll)
, then ngAfterViewChecked
is not called anymore.
How is it possible to call a function when an element is scrolled, but avoid Angular's change detection?
I have a large ponent, and I would like to avoid unnecessary change detections to increase performance.
I added changeDetection: ChangeDetectionStrategy.OnPush
to the @Component
.
I would like to update the style of an element if it is scrolled. Unfortunately Angular runs the change detection, every time I scroll that element.
I tried to add an event listener to the native element to avoid this, but the change detection is still running again when I scroll:
@ViewChild('my_element') my_element_ref: ElementRef;
ngOnInit() {
this.my_element_ref.nativeElement.addEventListener('scroll', this.updateStyle);
}
ngAfterViewChecked() {
console.log('check');
}
The ngAfterViewChecked
is called even if this.updateStyle
is an empty function.
But if I ment out this.my_element_ref.nativeElement.addEventListener('scroll', this.onScroll)
, then ngAfterViewChecked
is not called anymore.
How is it possible to call a function when an element is scrolled, but avoid Angular's change detection?
Share Improve this question asked May 28, 2019 at 9:32 Iter AtorIter Ator 9,34822 gold badges89 silver badges184 bronze badges3 Answers
Reset to default 2I would suggest you use ngZone.runOutsideAngular.
constructor (private zone : NgZone) {}
ngAfterViewInit () : any {
this.zone.runOutsideAngular(() => {
window.addEventListener('scroll', (e)=> {
console.log( 'scroll event fired' );
});
});
}
You might want to look at ChangeDetectorRef API. Specifically you would detach the change detection for the ponent using detach() (maybe in the constructor like below) and then mark ponent for change in your scroll function via markForCheck().
constructor(public cd: ChangeDetectorRef) {
this.cd.detach();
}
this.cd.markForCheck();
Below links for your reference.
https://blog.angularindepth./everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f
https://angular.io/api/core/ChangeDetectorRef
just inject NgZone
in your constructor and then subscribe to an event like this:
this.ngZone.runOutsideAngular(() => {
....addEventListener('...);
});
keep in mind that change detection will not be called in this case, so you won't be able to change styles with template binding. It should be changed by native javascript or using Renderer2
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745467303a4628972.html
评论列表(0条)