Cdk virtual scrolling issue

Viewed 23862

Does any one met the issue of angular 7 cdk virtual scrolling working abnormally in mat-tab group.

https://github.com/angular/material2/issues/13981

My city component template looks like that

<cdk-virtual-scroll-viewport class="list-container" [itemSize]="50" minBufferPx="200" maxBufferPx="400" (scrolledIndexChange)="getNextBatch($event)">
  <div *cdkVirtualFor="let state of statesObservable | async; trackBy: trackByFn" class="list-group-item state-item">
    <div class="state">{{state.name}}</div>
    <div class="capital">{{state.capital}}</div>
  </div>
</cdk-virtual-scroll-viewport>

When put this city component to the mat-tab-group as the second tab

<mat-tab-group>
  <mat-tab label="Country">
    <app-country></app-country>
  </mat-tab>
  <mat-tab label="City">
    <app-city></app-city>
  </mat-tab>
</mat-tab-group>

The result looks like belenter image description hereow:

The stackblitz code is here: https://stackblitz.com/edit/angular7-virtual-scroll-issue

Does anyone have some idea for this issue?

5 Answers

You need to lazy load the tab content by declaring the body in a ng-template with the matTabContent attribute. This way, the viewport size is calculated only when the tab is shown.

  <mat-tab label="City">
    <ng-template matTabContent>
      <app-city></app-city>
    </ng-template>
  </mat-tab>

See: https://material.angular.io/components/tabs/overview#lazy-loading

The question has been asked some time ago, but there is a solution which is not a workaround.

First you need the Viewport Reference:

@ViewChild(CdkVirtualScrollViewport, {static: false}) cdkVirtualScrollViewport: CdkVirtualScrollViewport;

Then you can call the Method checkViewportSize() when the size of the Viewport has changed. Before you call this method you need to update the style height of the Viewport container.

this.heightChange$.subscribe(() => {
    this.cdkVirtualScrollViewport.checkViewportSize();
});

Works for me, thanks!

  @ViewChild(CdkVirtualScrollViewport) viewport: CdkVirtualScrollViewport;

  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.viewport.checkViewportSize();
  }

Use ItemSize only. Avoid Max and Min Buffer.

<cdk-virtual-scroll-viewport class="list-container" [itemSize]="50" >

It needs to be the exact pixel height of a single item.

Related