Skip to content
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

When lazy loading items from a server, I want to show an item placeholder until the requested item is available #481

Open
Legioth opened this issue Aug 18, 2017 · 4 comments

Comments

@Legioth
Copy link

Legioth commented Aug 18, 2017

I want to use <iron-list> with "millions" of items from that are fetched lazily from the server whenever the user scrolls close to the boundary of what's currently available, but what I want to avoid is the phenomenon seen in e.g. https://www.webcomponents.org/element/PolymerElements/iron-scroll-threshold/demo/demo/document.html that momentum scrolling stops while waiting for more items.

Instead, I'd like to initialize <iron-list> with scrollbars based on the actual number of backend items (or an approximation thereof). If the user scrolls to a region for which there are no items, I'd like to show placeholders for the items that are currently being fetched, similarly to how e.g. <vaadin-grid> with a dataProvider shows empty rows.

I can set the length of the array based on the total item count, but only populate values for the indices that have actually been fethed. The problem is that <iron-list> ignores the item if items[idx] is null-ish. For small-ish data sets, I can work around this by eagerly populating all indices in items with the same placeholder item, but that's not practical for larger data sets.

I have two different ideas for how this could be done, each with their own pros and cons:

  1. Add a new property, e.g. placeholderItem that is used instead of a null-ish value retrieved from items.
  2. Add support for a special empty template (e.g. <template class="empty"><my-spinner></my-spinner></template> that is used instead of the regular template when getting a null.

placeholderItem would seem more convenient if I want to show the same structure for missing items, just with empty values. A custom template is instead easier to use if I want to use some completely different HTML structure. A different structure can also be achieved with placeholderItem with the use of dom-if in the regular template. It also seems like placeholderItem can be implemented quite easily, whereas introducing another template would be a quite complicated affair.

@Westbrook
Copy link
Contributor

I've worked with the idea of the placeholderItem in the form of defaultItem before in a branch of my own and offered this PR #342 to support a similarly written issue #244.

The code therein was for the 1.x branch, but you can find the 2.x version of the same updates at https://github.com/Westbrook/iron-list/tree/2.0-ps if there was some new traction behind adding this to the feature set, I'd be happy to do some further clean up and enter a PR around the functionality.

@ernsheong
Copy link

ernsheong commented Nov 23, 2017

@Legioth I am able to achieve this effect by creating my own custom element to act as the row item. Within the row item custom element, if the backing data object is empty, I render a placeholder view (just a dom-if).

To make this work, you need to precompute the total number of rows (say 200), i.e. let the server tell you that. Then for your first batch of items loaded from the server (say page size of 20), you need to generate 180 empty objects and populate it within the full items array. Hence the iron-list will receive an array of 200 items (20 real and 180 dummy). As the user scrolls down, install an event listener (throttled) to read the lastVisibleIndex and determine if we need to fetch more items (maintain a variable to hold the next index to load, i.e. 21). When new items do come in, we have to splice the new items in to prevent the iron-list from doing a full list and scroll reset (use this.splice or this.notifySplices)

This works really well in my case. www.pagedash.com (Check it out in production!) It's an alternative to Evernote Web Clipper.

@Legioth
Copy link
Author

Legioth commented Nov 23, 2017

@ernsheong That approach works nicely when you have 200 items all in all and need to generate and populate 180 empty objects. It breaks down when you have 10 000 items and need to generate and populate 9 980 instances.

@ernsheong
Copy link

ernsheong commented Nov 23, 2017

At that level it might make sense to "cheat" and generate more as the user gets closer, but yeah it depends on what the application requirements are.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants