21

I would like to use cdk-virtual-scroll-viewport in a TimeLine view with items of different heights.

So setting itemSize="x" which, according to the documentation refers to The size of the items in the list (in pixels), is unpractical.

autosize is not yet available.

Is it possible at all to use virtual/endless scrolling with cdk-virtual-scroll-viewport vith variable item sizes?

Update

I was looking for alternative virtual/endless scrolling solutions and, I hardly can believe, it seems there is no solution which works with dynamic row height, even with https://github.com/rintoj/ngx-virtual-scroller it's not recommended.

Update 2, July 2019

Since meanwhile there is still no solution, I believe the "good enough" way to work around this would be to load a fixed number of items, and add a button to load more items at the bottom of the list, like in this example: https://stackblitz.com/edit/ang-mat-load-more

2

7 Answers 7

11

autosize works for me.

Try to install:

"@angular/cdk": "6.2.0",
"@angular/cdk-experimental": "6.2.0"

and then import ScrollingModule into your module:

import {ScrollingModule} from "@angular/cdk-experimental";

imports: [ScrollingModule]

then you can use autosize property like below:

 <cdk-virtual-scroll-viewport autosize style="height: 100%">
6
  • 4
    I think you need both the stable and experimental module imported: import { ScrollingModule as ExperimentalScrollingModule } from '@angular/cdk-experimental/scrolling'; import { ScrollingModule } from '@angular/cdk/scrolling'; imports: [ScrollingModule, ExperimentalScrollingModule]
    – Preda7or
    Commented Apr 15, 2021 at 10:20
  • 1
    "@angular/cdk": "12.2.8", "@angular/cdk-experimental": "12.2.8" If i have set only autosize, i get an error Error: cdk-virtual-scroll-viewport requires the "itemSize" property to be set.
    – Juri
    Commented Oct 6, 2021 at 6:43
  • @Juri did you find the solution?
    – Maurice
    Commented Oct 21, 2021 at 21:40
  • 1
    @Maurice i guess somithing with my module configuration is wrong, adden both modules in shared module and now it seems to work. Thx for asking
    – Juri
    Commented Oct 22, 2021 at 9:17
  • 2
    Thanks a lot for your answer, it si working for me ... The strange thing is that in "@angular/cdk": "^15.2.0" we still do not have this behaviour Commented Mar 12, 2023 at 12:03
4

Finally I found the solution: In my case, I recently use @angular/cdk version 12.2.13 and so you should install too @angular/cdk-experimental with version 12.2.13 (the same version).

Go to app.module.ts: add this line:

import { ScrollingModule as ExperimentalScrollingModule } from '@angular/cdk-experimental/scrolling';
import { ScrollingModule } from '@angular/cdk/scrolling';

and in imports:

[ScrollingModule,
    ExperimentalScrollingModule]

Then do this:

<cdk-virtual-scroll-viewport
          autosize
          style="height: 100%"
          class="container"
        >
your content
</cdk-virtual-scroll-viewport>

it worked for me.

0
2

Until this feature is offered in the CDK I got around it by listening to the onscroll event of the native element then respond when the scroll offset to the bottom is 0

@ViewChild(CdkVirtualScrollViewport, { static: false })
public virtualScrollViewport?: CdkVirtualScrollViewport;

...

ngAfterViewInit() {
  this.virtualScrollViewport.elementRef.nativeElement.onscroll = (e) => { this.onScroll(e) };
}

onScroll(e) {
  var scrollOffset = this.virtualScrollViewport.measureScrollOffset("bottom");

  if (scrollOffset == 0) {
    this.fetchMoreData();
  }
}
2
  • May I ask how this solves the item height problem? The point of the virtual scroll was to render the items only as they are shown in the viewport, and for that reason to be able to calculate that requires a fixed item height. Your solution seems to be about loading the next items, not solving the variable height issue.
    – dormant
    Commented Dec 28, 2022 at 21:03
  • 1
    One issue with dynamic heights, or in my case expandable rows, is that scrolling will sometimes load items prematurely or not at all because the trigger points are inconsistent. This work around will provide a more reliable experience for when to load the next batch of items so that the user is never stuck at the bottom of the scrollable area. However, it does not address the issue of only rendering visible items. Commented Jan 11, 2023 at 15:04
0

itemSize="x" doesn't help set the height... you'd have to use CSS to assign an arbitary height yourself.

coming to your question, variable item sizes should not be a problem with the virtual scroll... you can change the array in this example to see the possibility & results very quickly.

0
0

This CSS works for me. No fixed height required:

<cdk-virtual-scroll-viewport class="viewport">  
   .......
</cdk-virtual-scroll-viewport>

.viewport { 
   display: contents;
}
1
0

The only thing that worked for me is the example of splaktar at stackblitz

Template:

<cdk-virtual-scroll-viewport [itemSize]="itemSize" class="example- 
viewport">
<div *cdkVirtualFor="let item of items"
   [style.height]="itemSize + 'px'">{{item}}</div>
</cdk-virtual-scroll-viewport>
<br>
<div>
<label for="height">Item Size:</label>
<input id="height" type="number" [(ngModel)]="itemSize">
</div>

component:

import {ChangeDetectionStrategy, Component} from '@angular/core';

@Component({
selector: 'cdk-virtual-scroll-overview-example',
styleUrls: ['cdk-virtual-scroll-overview-example.css'],
templateUrl: 'cdk-virtual-scroll-overview-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollOverviewExample {
items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
itemSize = 80;
}
-1

It is possible to set cdkvirtualscrollviewport height dynamically with [ngStyle]

          <cdk-virtual-scroll-viewport
        itemSize="parent?.children.length"
        [ngStyle]="{'height.px': parent?.children.length<10? parent?.children.length*42 :250 }"
      >
1
  • could you explai a bit more? What is parent? exactly? and height.px ?
    – Maurice
    Commented Oct 21, 2021 at 22:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.