components icon indicating copy to clipboard operation
components copied to clipboard

bug(cdk-virtual-scroll): Only shows a few items when using scrollWindow property

Open mcrtricolor opened this issue 2 years ago • 26 comments

Is this a regression?

  • [ ] Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

When you use the scrollWindow property it only renderers the initial items (the ones inside your min and max buffer settings) after that it is just blank spaces.

It also happens at the angular material show case example, it only show the first 21 items. I tried to use the checkViewportSize() method but of no use.

https://material.angular.io/cdk/scrolling/overview

Reproduction

https://stackblitz.com/edit/angular-1uahhp?file=src/app/cdk-virtual-scroll-window-scrolling-example.ts

Steps to reproduce:

  1. It already happens on the virtual scrolling window example.

Expected Behavior

It should render new items as you scroll down the page, eventually rendering all the items.

Actual Behavior

It stops rendering items after the initial ones are rendered.

Environment

  • Angular: 14.1.0
  • CDK/Material: 14.1.0
  • Browser(s): Chrome, Firefox
  • Operating System (e.g. Windows, macOS, Ubuntu): Windows, macOS

mcrtricolor avatar Jul 25 '22 13:07 mcrtricolor

Hi Zach, thanks for the notice!

It's now edited with the proper link.

Thanks again

Martín Corbacho

El lun, 25 jul 2022 a las 13:59, Zach Arend @.***>) escribió:

Hello @mcrtricolor https://github.com/mcrtricolor , I clicked the above stackblitz link, but it takes me to the stackblitz homepage. Sometimes the URL in the address bar isn't the URL for sharing. Could you please click "Share" on the top bar to get the link to the editor and share it here?

[image: image] https://user-images.githubusercontent.com/7720245/180833392-7a97847b-0a17-4071-896d-1965b44253fc.png

— Reply to this email directly, view it on GitHub https://github.com/angular/components/issues/25336#issuecomment-1194352800, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQYE523MWLBPR5LUZGXRSXDVV3BVVANCNFSM54SJXLAA . You are receiving this because you were mentioned.Message ID: @.***>

mcrtricolor avatar Jul 25 '22 17:07 mcrtricolor

Thanks for reporting @mcrtricolor , I'm confirming that I can reproduce on both my mac and my windows machine.

Windows 10 Enterprise, Version 20H2 | Crhome Version 103.0.5060.134 (Official Build) (64-bit) MacOS 12.4 (21F79) | Chrome Version 103.0.5060.134 (Official Build) (x86_64)

zarend avatar Jul 25 '22 17:07 zarend

Do you know what version this used to work with?

zarend avatar Jul 25 '22 17:07 zarend

I think this property scrollWindow is new, i was using 14.0.6 and had to update it to 14.1.0 in order to use it.

Thanks.

Martín Corbacho

El lun, 25 jul 2022 a las 14:26, Zach Arend @.***>) escribió:

Do you know what version this used to work with?

— Reply to this email directly, view it on GitHub https://github.com/angular/components/issues/25336#issuecomment-1194385477, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQYE52YP4YFAYNL6TNZ65EDVV3E4RANCNFSM54SJXLAA . You are receiving this because you were mentioned.Message ID: @.***>

mcrtricolor avatar Jul 25 '22 17:07 mcrtricolor

I tried upgrading to 14.1.0 in https://stackblitz.com/edit/angular-vszuks, and it didn't seem to help. @crisbeto is this something you could look at?

zarend avatar Jul 28 '22 00:07 zarend

I got this bug after upgrading from 13.3.9 to 14.1.0

aydex avatar Jul 28 '22 04:07 aydex

I also can confirm this bug. Just take a look at the StackBlitz demo linked in the official CDK docs: https://stackblitz.com/run?file=src%2Fapp%2Fcdk-virtual-scroll-window-scrolling-example.ts

The example should render 10k elements but only the first 23 elements are rendered

daniel-zero avatar Aug 22 '22 21:08 daniel-zero

I can also confirm this issue on the StackBlitz demo page. I tried different browsers as well such as Chrome and Edge and both show the same behavior.

ckieber avatar Oct 05 '22 04:10 ckieber

looks like it is still an issue in 14.2.5

mikeyamashita avatar Oct 13 '22 17:10 mikeyamashita

I spent a bit of time investigating this the other day. As far as I can tell, this is a problem with the demo, rather than the component. For some reason the document doesn't end up receiving the scroll events when it gets forked to Stackblitz which is why it doesn't re-render. If you run into this issue, you should check that the top-level document is actually scrollable and not some container further down.

crisbeto avatar Oct 23 '22 15:10 crisbeto

Any news on this? thanks in advance

mcrtricolor avatar Nov 22 '22 13:11 mcrtricolor

I could not get it to work in a regular angular project. I used 'CdkScrollable' instead of 'scrollWindow' as a workaround then massaged the html and css to make the demo function the same: https://stackblitz.com/edit/angular-sygccx-yxae5u?file=src%2Fapp%2Fcdk-virtual-scroll-window-scrolling-example.css

mikeyamashita avatar Nov 22 '22 19:11 mikeyamashita

Hi, any news on this issue?

mcrtricolor avatar Jan 27 '23 14:01 mcrtricolor

check that the top-level document is actually scrollable and not some container further down.

@crisbeto's observation is correct - I noticed the same issue when the virtual scroll had ancestors with overflow property.

I'm using mat-sidenav & mat-drawer containers. These also interfere with document scrolling but I can't remove them.

image

Would appreciate a way to make scrollWindow work with ancestors that have overflow property set, or a workaround..

anisabboud avatar Mar 21 '23 13:03 anisabboud

Update: I found a solution for my case (virtual scroll inside a mat-drawer-content, which expands to fit the available height).

Instead of using the scrollWindow directive, Angular CDK offers another directive cdkVirtualScrollingElement which can be applied to the scrolling ancestor. See: https://material.angular.io/cdk/scrolling/overview#separate-viewport-and-scrolling-element.

image

For my use-case, I applied this directive to the top-most div inside the drawer-content, along with height: 100%.

  <mat-drawer-content>
    <div style="height: 100%" cdkVirtualScrollingElement>
      <h2>My List</h2>
      <cdk-virtual-scroll-viewport itemSize="64">
        <my-list-item *cdkVirtualFor="let element of myList; trackBy: trackById" />
      </cdk-virtual-scroll-viewport>
    </div>
  </mat-drawer-content>

This way I don't need to set a specific height on the virtual-scroll-viewport and it can expand to fill the available space.

anisabboud avatar Mar 21 '23 19:03 anisabboud

If someone having this issue: the issue is only on Angular 14 with Material 14. Even the example on the Material page doesn't work. The one with Material 15 and Angular 15 - works fine.

hackmajoris avatar Apr 26 '23 19:04 hackmajoris

Any new on that?

I also tried to use "cdkVirtualScrollingElement" outside of my component (which has the "cdk-virtual-scroll-viewport") to set the <main> as the scroll-container (same as the result of scrollWindow) but the scroll-container remains the "cdk-virtual-scroll-viewport", if I use the "scrollWindow" I get the same issue as OP

Danieliverant avatar Oct 03 '23 08:10 Danieliverant

Any new on that?

I also tried to use "cdkVirtualScrollingElement" outside of my component (which has the "cdk-virtual-scroll-viewport") to set the <main> as the scroll-container (same as the result of scrollWindow) but the scroll-container remains the "cdk-virtual-scroll-viewport", if I use the "scrollWindow" I get the same issue as OP

Is upgrading to Angular >15 an option?

hackmajoris avatar Oct 03 '23 09:10 hackmajoris

Any new on that? I also tried to use "cdkVirtualScrollingElement" outside of my component (which has the "cdk-virtual-scroll-viewport") to set the <main> as the scroll-container (same as the result of scrollWindow) but the scroll-container remains the "cdk-virtual-scroll-viewport", if I use the "scrollWindow" I get the same issue as OP

Is upgrading to Angular >15 an option?

We're using v16+ but my issue is not related to material components or something like that

Danieliverant avatar Oct 03 '23 10:10 Danieliverant

Any new on that?

I also tried to use "cdkVirtualScrollingElement" outside of my component (which has the "cdk-virtual-scroll-viewport") to set the <main> as the scroll-container (same as the result of scrollWindow) but the scroll-container remains the "cdk-virtual-scroll-viewport", if I use the "scrollWindow" I get the same issue as OP

Is upgrading to Angular >15 an option?

We're using v16+ but my issue is not related to material components or something like that

Got it. Usually, I had the issue when I do set the wrong row height(item size) for the elements inside the virtual-scroll.

I have a working example here, you can check how it behaves on your side:

<cdk-virtual-scroll-viewport [itemSize]="itemSizeInPixels" [maxBufferPx]="1200">
        <mat-list-item  class="user-list-item-height" *cdkVirtualFor="let userListItem of items; trackBy: trackBy">          
            <div fxFlex="100">          
              {{ userListItem?.user.firstName + ' ' + userListItem?.user.lastName }}
            </div>              
        </mat-list-item>
</cdk-virtual-scroll-viewport>
.user-list-item-height {
  height: 70px !important;
}

Check also in the package.json that you have cdk version > 14. I have "@angular/cdk": "15.2.1".

hackmajoris avatar Oct 04 '23 07:10 hackmajoris

Any new on that?

I also tried to use "cdkVirtualScrollingElement" outside of my component (which has the "cdk-virtual-scroll-viewport") to set the <main> as the scroll-container (same as the result of scrollWindow) but the scroll-container remains the "cdk-virtual-scroll-viewport", if I use the "scrollWindow" I get the same issue as OP

Is upgrading to Angular >15 an option?

We're using v16+ but my issue is not related to material components or something like that

Got it. Usually, I had the issue when I do set the wrong row height(item size) for the elements inside the virtual-scroll.

I have a working example here, you can check how it behaves on your side:

<cdk-virtual-scroll-viewport [itemSize]="itemSizeInPixels" [maxBufferPx]="1200">
        <mat-list-item  class="user-list-item-height" *cdkVirtualFor="let userListItem of items; trackBy: trackBy">          
            <div fxFlex="100">          
              {{ userListItem?.user.firstName + ' ' + userListItem?.user.lastName }}
            </div>              
        </mat-list-item>
</cdk-virtual-scroll-viewport>
.user-list-item-height {
  height: 70px !important;
}

Check also in the package.json that you have cdk version > 14. I have "@angular/cdk": "15.2.1".

we're using the "autoSize" options from the experimental CDK, and yes our CDKs are aligned with our Angular versions

Danieliverant avatar Oct 04 '23 08:10 Danieliverant

Any new on that?

I also tried to use "cdkVirtualScrollingElement" outside of my component (which has the "cdk-virtual-scroll-viewport") to set the <main> as the scroll-container (same as the result of scrollWindow) but the scroll-container remains the "cdk-virtual-scroll-viewport", if I use the "scrollWindow" I get the same issue as OP

Is upgrading to Angular >15 an option?

We're using v16+ but my issue is not related to material components or something like that

Got it. Usually, I had the issue when I do set the wrong row height(item size) for the elements inside the virtual-scroll. I have a working example here, you can check how it behaves on your side:

<cdk-virtual-scroll-viewport [itemSize]="itemSizeInPixels" [maxBufferPx]="1200">
        <mat-list-item  class="user-list-item-height" *cdkVirtualFor="let userListItem of items; trackBy: trackBy">          
            <div fxFlex="100">          
              {{ userListItem?.user.firstName + ' ' + userListItem?.user.lastName }}
            </div>              
        </mat-list-item>
</cdk-virtual-scroll-viewport>
.user-list-item-height {
  height: 70px !important;
}

Check also in the package.json that you have cdk version > 14. I have "@angular/cdk": "15.2.1".

we're using the "autoSize" options from the experimental CDK, and yes our CDKs are aligned with our Angular versions

I believe you need Angular 16 to get use of autoSize from experimental CDK.

hackmajoris avatar Oct 04 '23 10:10 hackmajoris

Using Angular 17 and Material 17 and there is no way to make this working with projections. I manage to solve the issue partially but doesn't load the list when the view disappears and reappears with ngIf.

zalito12 avatar Apr 17 '24 01:04 zalito12

So... After a lot of research and dive in angular and cdk base code, I came up with a solution. Bonus track: With scroll restoration 🔥

In my case, I'm using a material Sidenav with a Toolbar and when I started designing the site I delegated all the scroll to the drawer content (mat-drawer-content).

That's why the scrollWindow wasn't working. Now I'm pretty sure that I should have refactored that decision and make the scroll responsability of the window again and probably I'll do that in a future but, honestly... when I realized that, it was too late and I already had spent hours trying to solve this.

The solution was to make a custom directive, just a copy of the original scrollWindow with my element as scrollable container, that simple. As I already had created an implementation for a custom ViewportScroller to override the angular default scroll restoration, I integrated both of the clasess.

You can find the code here: https://gist.github.com/zalito12/1bbdd3b986531346d1a4e710ac266dbe

If anyone is in this situation, I advise to reconsider your design decisions and if it make senses to have the scroll viewport in a component instead of the window, but as some people say that cdk scrolling is not working correctly with projections, maybe this could help, actually I'm using projections on the drawer content and this solution also works!

zalito12 avatar Apr 17 '24 23:04 zalito12