-
Notifications
You must be signed in to change notification settings - Fork 6.8k
virtual scroll: implement scrollTo functions #11498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -151,6 +151,11 @@ export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy { | |||
} | |||
} | |||
|
|||
/** Get the offset for the given index. */ | |||
getOffsetForIndex(index: number) { | |||
return index * this._averager.getAverageItemSize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this case is a little more complex. we should use the currently rendered content as a reference point and fallback to the estimate for items that aren't rendered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow? Can you explain a bit more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The average item size is just a best guess, but for items that are already rendered we don't have to guess, we can just measure them. For ones that are not rendered we use the guess.
e.g. Let's say elements 50-100 are rendered. I'm scrolled to item 55, I want to go to 45. I can measure items 50-55 + 5*averageSize for the non-rendered items
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The more I think about this the more I think this is a bad idea. Would you be ok with throwing an error here and saying its not supported? The delta could be way off very easily. I think we would just get plagued with bugs if we tried to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it could be way off but I have logic to slowly correct the error in the scroll listener code, so I think it should be ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. I think we need a mechanism to cache the index of the item with its respective size so i can calculate the deltas. Thoughts?
@@ -37,4 +37,7 @@ export interface VirtualScrollStrategy { | |||
|
|||
/** Called when the offset of the rendered items changed. */ | |||
onRenderedOffsetChanged(); | |||
|
|||
/** Get the offset for the given index. */ | |||
getOffsetForIndex(index: number); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets call it getScrollOffsetForIndex
just to be super clear
const left = this.orientation === 'horizontal' ? offset : 0; | ||
|
||
let shouldScroll = true; | ||
if (options.lazy) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this logic is quite right because the rendered content may be larger than the viewport.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your right. I changed it to measure the viewport size rather than content.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if lazy scrolling is a common enough use case to be something we want to include in the API. It's pretty easy to implement on top if we just provide the basic functionality
src/cdk/platform/features.ts
Outdated
@@ -27,6 +27,25 @@ export function supportsPassiveEventListeners(): boolean { | |||
return supportsPassiveEvents; | |||
} | |||
|
|||
/** Cached result of whether the user's browser supports scroll behaviors. */ | |||
let scrollSupport = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you mean to init to null?
@mmalerba - Any idea why the tests fail when using scrollTo? |
Any update on this? |
nudge @mmalerba |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about that, this fell off my radar after vacation
@@ -37,4 +37,7 @@ export interface VirtualScrollStrategy { | |||
|
|||
/** Called when the offset of the rendered items changed. */ | |||
onRenderedOffsetChanged(); | |||
|
|||
/** Get the offset for the given index. */ | |||
getScrollOffsetForIndex(index: number); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we may want to put the whole scrollToIndex
function as part of the strategy and just have the viewport delegate. While the autosize strategy might not know exactly where the item is, I think we can create an implementation later on that just kind of guesses. It would require the strategy to have full control over what the scroll method does though, not just spitting back an offset.
@@ -151,6 +151,11 @@ export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy { | |||
} | |||
} | |||
|
|||
/** Get the offset for the given index. */ | |||
getScrollOffsetForIndex() { | |||
throw new Error('Offset location is not supported with autosize.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's say "not currently supported", this sounds like it never will be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean that the scrollToIndex will not be supported for autosize in initial version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The autosize strategy will probably stay in cdk-experimental a little longer than the fixed size strategy, while we work out some of the bugs. This will be implemented before it goes into cdk
const left = this.orientation === 'horizontal' ? offset : 0; | ||
|
||
let shouldScroll = true; | ||
if (options.lazy) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if lazy scrolling is a common enough use case to be something we want to include in the API. It's pretty easy to implement on top if we just provide the basic functionality
Closing given #12272 |
…12272) Note: `scrollToIndex` currently does not work with the `AutoSizeVirtualScrollStrategy`. Support for this will be added in a future PR. This PR is based off #11498 by @amcdnl. I removed the `lazy` option from #11498 to avoid bloating the API. I'm not sure how common the use case is, and its relatively simple to implement on top using the current APIs.
…12272) Note: `scrollToIndex` currently does not work with the `AutoSizeVirtualScrollStrategy`. Support for this will be added in a future PR. This PR is based off #11498 by @amcdnl. I removed the `lazy` option from #11498 to avoid bloating the API. I'm not sure how common the use case is, and its relatively simple to implement on top using the current APIs.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This PR adds the ability for users to scroll to an offset or an index with the ability to do so smoothly and/or lazily.
Partial fix for #10116 (
scrollToIndex
only supported for fixed size strategy)