Skip to content

CdkVirtualScrollViewport rendered range is not correct when going from a large list to a smaller list #19029

Closed
@rsc092020

Description

@rsc092020

Bug, feature request, or proposal:

The rendered range is not set to the expected value when changing from a longer data list to a shorter one. I think this only happens if you are at the very top of the list (i.e. the rendered range start is 0).

What is the expected behavior?

The end of the rendered range shouldn't be higher than the length of the data list.

What is the current behavior?

If the start of the rendered range is 0, and it is changing to a smaller list than the previous one, the end of the rendered range doesn't change. This causes the rendered range to be higher than the length of the data. Also, another issue is that because the rendered range doesn't change at all in this case, there will be no emitted event to the viewChange property on CdkVirtualForOf.

What are the steps to reproduce?

https://stackblitz.com/edit/angular-virtual-scroll-issue

What is the use-case or motivation for changing an existing behavior?

I'm swapping out lists to show search results in the virtual scroll, and I implemented an infinite scroll based on subscribing to viewChange in DataSource.connect(). This issue is causing the viewChange event to not get emitted in a situation where I think it should be, so I am not able to react to an event and load more data into the list.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

I'm on these versions currently in my project, but I'm fairly certain this behavior has existed many versions back:
Material: 8.2.3
Angular: 8.2.14
TypeScript: 3.5.3

Is there anything else we should know?

I believe the issue is somewhere in the calculations in FixedSizeVirtualScroll._updateRenderedRange: https://github.com/angular/components/blob/master/src/cdk/scrolling/fixed-size-virtual-scroll.ts#L118-L152.

I think I have a workaround directive, but I'm not sure if it will cause other issues:
The directive subscribes to the dataStream of CdkVirtualForOf, and if the end of the rendered range for the viewport is greater than the data length for the event, then I make a call like this: CdkVirtualScrollViewport.setRenderedRange({start: previousStart, end: data.length}).

Metadata

Metadata

Assignees

Labels

P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: cdk/scrolling

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions