angular-ui / ui-scroll

Unlimited bidirectional scrolling over a limited element buffer for AngularJS applications
http://angular-ui.github.io/ui-scroll/demo/
MIT License
326 stars 107 forks source link

Trying to understand enqueueFetch logic (unable to fetch data in window list) #240

Closed ornic closed 5 months ago

ornic commented 4 years ago

And hello again :)

Now I had some "fun" time with ngAnimation and duplication of view container in the moment of transition between views.

I will try to make plunker later, but it is not so easy (for me). So, for now, a thousand words.

There are two views: list of objects (with ui-scroll and viewport on window) and selected object. I'm going from the object view to the list view. And for the moment (in the moment of ui-scroll init) both these views are in the DOM (since ngAnimate works whis way, I assume).

image

When the view of selected object is more than (I assume) 2 heights of the window, viewport.shouldLoadBottom() in enqueueFetch https://github.com/angular-ui/ui-scroll/blob/a957d07c600a4b19984884f446bd2c44194103d3/src/ui-scroll.js#L370-L379 returns false (the bottom of the viewport is way below the end of screen) and so, the Datasource.get() is asked only about negative indexes of data (viewport.shouldLoadBottom() is true). And in the end I see zero data (get() from negative indexes returns []).

For now I patched this by changing logic in https://github.com/angular-ui/ui-scroll/blob/a957d07c600a4b19984884f446bd2c44194103d3/src/modules/viewport.js#L70-L72 to

return !buffer.eof && (buffer.length === 0 || viewport.bottomDataPos() < viewport.bottomVisiblePos() + bufferPadding());

So when we do not have any information in the buffer, we always try to ask for data.

Now I testing this patch and trying to understand was there a better place to make changes. :)

dhilt commented 4 years ago

Perhaps I didn't catch the problem, but looking at shouldLoadBottom logic I'd recommend to pay special attention to the role of bufferPadding method. The value it returns depends on padding parameter, which is determined at the layer of the consumer App:

function bufferPadding() {
  return viewport.outerHeight() * padding;
}

By making padding parameter big enough, you may pass the condition

bottomDataPos() < bottomVisiblePos() + bufferPadding()

without any additional changes. The meaning of the padding parameter can be taken from the doc:

padding - expression, optional - extra height added to the visible area for the purpose of determining when the items should be created/destroyed. The value is relative to the visible height of the area, the default is 0.5 and the minimal value is 0.3.

This also answers to your assumptions regarding "2 heights of the window": if you don't define padding parameter, shouldLoadBottom will return false when the last rendered row's bottom coordinate is more than 150% of the viewport's height.