Sergiu Molnar
Sergiu Molnar

Reputation: 1020

How to use cdk-virtual-scroll with ngx-infinite-scroll

I've upgraded my Angular project dependencies:

And after that, the infinite scroll (with virtualization) stopped working.

What I observed is that the cdk-virtual-scroll-viewport does not add a scroll anymore if the scrollWindow property is set to false and the ngx-infinite-scroll needs that property to be set to false.

<cdk-virtual-scroll-viewport
  *ngIf="items.length"
  class="virtualScrollViewport"
  itemSize="80"
  minBufferPx="400"
  maxBufferPx="600"
  infiniteScroll
  [infiniteScrollDistance]="1"
  [infiniteScrollThrottle]="50"
  [infiniteScrollDisabled]="loading || !loaded || !canLoadMoreItems"
  [scrollWindow]="false"
  (scrolled)="onScroll()"
>
  <div><p class="text-bold">Available items</p></div>
  <mat-card *cdkVirtualFor="let itemof items; trackBy: trackByFunction">
    <mat-card-content>
      ...
    </mat-card-content>
  </mat-card>

  <mat-progress-bar *ngIf="loading && items?.length" mode="indeterminate"></mat-progress-bar>
</cdk-virtual-scroll-viewport>

Now the scroll is not displayed anymore (.cdk-virtual-scrollable class is not added anymore). Without the [scrollWindow]="false" it is, but the infinite scroll is not working because based on their documentation this property is necessary. So, these two things go head to head.

Has anyone faced the same issue and found a workaround for this?

Upvotes: 2

Views: 2129

Answers (2)

I have working solution for latest Angular.

@ViewChild(CdkVirtualScrollViewport)
set scrollEvent(scrollRef: CdkVirtualScrollViewport) {
  const threshold = 5; //pixels from bottom
  const scrollRefElement = scrollRef.getElementRef().nativeElement;
  if (scrollRef) {
    scrollRef.elementScrolled().subscribe(() => {
      console.log("scrolled");
      const isNearBottom =
        scrollRefElement.scrollHeight > 0 &&
        scrollRefElement.scrollTop + scrollRefElement.clientHeight >=
        scrollRefElement.scrollHeight - threshold;

      if (isNearBottom) {
        this.loadMoreChat();
        console.log("to fetch old chats");
      }
    });
  }
}

Upvotes: 0

DanielWaw
DanielWaw

Reputation: 699

@ViewChild(CdkVirtualScrollViewport)


 set scrollEvent(scrollRef: CdkVirtualScrollViewport) {if (scrollRef) {
  if (
    //note: scrolled container size must be greater than 0, we have to scroll from the top and bottom must have an offset smaller than 50 to trigger
    scrollRef.measureRenderedContentSize() > 0 &&
    scrollRef.measureScrollOffset("top") !== 0 &&
    scrollRef.measureScrollOffset("bottom") < 50
  ) {
    this.scrolled.emit();
  }
} }

I just have the same problem and I came up with a workaround. So You can listen to the scroll event by Yourself and add Your own rule of scroll event display. So in my case, I check if the element has height, we start scrolling from the top, and if the bottom is at least 50px. This works but I am still looking for a better solution.

Upvotes: 3

Related Questions