components
components copied to clipboard
bug(cdk-virtual-scroll): Only shows a few items when using scrollWindow property
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:
- 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
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: @.***>
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)
Do you know what version this used to work with?
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: @.***>
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?
I got this bug after upgrading from 13.3.9 to 14.1.0
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
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.
looks like it is still an issue in 14.2.5
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.
Any news on this? thanks in advance
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
Hi, any news on this issue?
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.
Would appreciate a way to make scrollWindow
work with ancestors that have overflow
property set, or a workaround..
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.
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.
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.
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
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?
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 OPIs upgrading to Angular >15 an option?
We're using v16+ but my issue is not related to material components or something like that
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 OPIs 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".
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 OPIs 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
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 OPIs 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.
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.
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!