Skip to content

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

Closed
wants to merge 6 commits into from

Conversation

amcdnl
Copy link
Contributor

@amcdnl amcdnl commented May 24, 2018

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)

@amcdnl amcdnl self-assigned this May 24, 2018
@amcdnl amcdnl requested a review from mmalerba May 24, 2018 18:50
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label May 24, 2018
@@ -151,6 +151,11 @@ export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy {
}
}

/** Get the offset for the given index. */
getOffsetForIndex(index: number) {
return index * this._averager.getAverageItemSize();
Copy link
Contributor

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

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

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

Copy link
Contributor Author

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);
Copy link
Contributor

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) {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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

@@ -27,6 +27,25 @@ export function supportsPassiveEventListeners(): boolean {
return supportsPassiveEvents;
}

/** Cached result of whether the user's browser supports scroll behaviors. */
let scrollSupport = true;
Copy link
Contributor

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?

@amcdnl
Copy link
Contributor Author

amcdnl commented May 31, 2018

@mmalerba - Any idea why the tests fail when using scrollTo?

@naveedahmed1
Copy link

Any update on this?

@amcdnl
Copy link
Contributor Author

amcdnl commented Jul 15, 2018

nudge @mmalerba

Copy link
Contributor

@mmalerba mmalerba left a 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);
Copy link
Contributor

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.');
Copy link
Contributor

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

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?

Copy link
Contributor

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) {
Copy link
Contributor

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

@amcdnl
Copy link
Contributor Author

amcdnl commented Jul 22, 2018

Closing given #12272

@amcdnl amcdnl closed this Jul 22, 2018
@amcdnl amcdnl deleted the scroll-to branch July 22, 2018 13:50
mmalerba added a commit that referenced this pull request Jul 25, 2018
…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.
mmalerba added a commit that referenced this pull request Jul 30, 2018
…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.
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes PR author has agreed to Google's Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants