orizens / ngx-infinite-scroll

Infinite Scroll Directive for Angular
https://www.npmjs.com/package/ngx-infinite-scroll
MIT License
1.23k stars 223 forks source link

How to implement infinite scroll with RouteReuseStrategy. Always emit scrolled events. #303

Closed Omi0 closed 5 years ago

Omi0 commented 5 years ago

In our application we are using RouteReuseStrategy to reapply elements.

Intinite scroll is used with the following settings: infiniteScroll [infiniteScrollDistance]="0" [infiniteScrollThrottle]="250" When component is detached, window scroll event handler is still persist for infiniteScroll, causing it to emitting (scrolled) event every scroll.

Why is it emitting scrolled events when its not in a viewport?

Omi0 commented 5 years ago

Probably ChangeDetector inside directive will work

orizens commented 5 years ago

whenever scroll event actually happens - it emits an event.

Omi0 commented 5 years ago

@orizens of course it does, how else we will paginate. And yet the most important part is "actually happens", but I need, before it is going to happen. Otherwise unless I through an error before, I will endlessly listen to window:scroll event and emit scroll events.

Omi0 commented 5 years ago

@orizens issue is closes. If anyone will experience the same problem the way I used it is, created custom RouterOutlet which implements onDetach and onAttach hooks for the component: `import {ComponentRef, Directive} from '@angular/core'; import {ActivatedRoute, RouterOutlet} from '@angular/router';

@Directive({ selector: 'app-router-outlet', }) export class AppRouterOutletDirective extends RouterOutlet {

detach(): ComponentRef { const instance: any = this.component; if (instance && typeof instance.onDetach === 'function') { instance.onDetach(); } return super.detach(); }

attach(ref: ComponentRef, activatedRoute: ActivatedRoute): void { super.attach(ref, activatedRoute); if (ref.instance && typeof ref.instance.onAttach === 'function') { ref.instance.onAttach(ref, activatedRoute); } } }`

onDetach hook looks as follows: onDetach() { this.isDetached = true; this.changeDetectorRef.detectChanges(); } In my case I used child components, but it doesn't really matter, to temprorarily disable infinite scroll you just need to do the following: infiniteScroll [infiniteScrollDisabled]="parentComponentDetached"

konstantinosftw commented 3 years ago

I have the same issue. The pages that are stored by my custom RouteReuseStrategy leave the scroll listener enabled, which fires on every scroll event on all future components the user visits. I can't really understand how to implement @Omi0 's solution above.

Is there a way to maybe set infiniteScrollDisabled to True when leaving the component and enabling it again when I navigate back to it?

Omi0 commented 3 years ago

@konstantinosftw I have even written an article about it. Scroll to 3 method. Hope it answers your question.

konstantinosftw commented 3 years ago

Hey @Omi0, I managed to make your solution work!

Tips for anyone stuck:

  1. Once you add all of Omi0's code to your project, you need to replace your app's <router-outlet> with the new <app-router-outlet> that you just created from the article.
  2. If you want to stop listeners that run on child components, you'll need to call changeDetectorRef.detectChanges() after any change you make in your parent's onDetach() function, like so:
onDetach() { 
  this.isDetached = true;   // or any other variable you are passing to the child
  this.changeDetectorRef.detectChanges();   // to detect the above change and actually send the variable to the child
}