angular-ui/ui-scroll

Skip intermediate requests to datasource if the scrolling was too fast.

Opened this issue · 15 comments

This is required mainly after I scroll down a few pages. Then drag the scroll thumb all the way to the top. The scroller can skip all the intermediate requests.

I am not sure if I am missing something but I did not find it in the docs.

I tried to add this logic in my datasource implementation. But looks like ui-scroll makes more than one call for a page (i guess its for the buffer). So its a little harder to put it here.

I am not sure I understand what problem you are trying to solve

Michael Feingold, President
401 Huehl RD, Suite 2A,
Northbrook, IL 60062
Email: mfeingold@hill30.com
Web: hill30.com http://www.hill30.com

On Mon, Oct 3, 2016 at 9:44 PM, subhash-periasamy notifications@github.com
wrote:

I tried to add this logic in my datasource implementation. But looks like
ui-scroll makes more than one call for a page (i guess its for the buffer).
so its making it a little harder.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#120 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIS36hz3vKP7lopYHbXenJArmSpiGrTks5qwb2HgaJpZM4KNF0N
.

dhilt commented

My understanding is that @subhash-periasamy wants to skip intermediate data requesting to prevent expensive rendering of the rows which would be removed after scroll ends. If it is so, I have to say that ui-scroll itself has no such functionality. But you really can improve the behaviour through the datasource extension. We have a useful demo on this, it is called Cache within datasource implementation. Please try it on and investigate sources. I believe this can help.

Thanks @dhilt . You are right about the problem. I will take a look at the cache implementation. But my rows have fields that changes very frequently and apart from that I will potentially have hundreds of thousands of rows.

In this case you should not relay on scrolling for doing this. Have a look
at the reload method instead.

Michael Feingold, President
401 Huehl RD, Suite 2A,
Northbrook, IL 60062
Email: mfeingold@hill30.com
Web: hill30.com http://www.hill30.com

On Tue, Oct 4, 2016 at 11:25 AM, subhash-periasamy <notifications@github.com

wrote:

Thanks @dhilt https://github.com/dhilt . You are right about the
problem. I will take a look at the cache implementation. But my rows have
fields that changes very frequently and apart from that I will potentially
have hundreds of thousands of rows.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#120 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIS36nVQxgDk_5DtmhjaKrH1f-M1VoNks5qwn4KgaJpZM4KNF0N
.

Hi @mfeingold,
I guess we have a disconnect here. Since @dhilt's suggestion is to look into cache within datasource, I am afraid that might not help since the data changes more frequently and the ui is talking to a backend table with million rows.

I don;t understand how reload will help me. Sorry if I am missing anything obvious.

Thanks!

If using cache covers your use case, by all means use it. One thing to
remember though is that cache does not prevent rendering - it only prevents
round trips to the server and the price for this is that all your hundreds
of thousands rows would be sitting in the cache.

as to reload - reload takes a parameter indicating the which row will
become the 1st one to be loaded. In other words you can refresh your view
starting from any row in your dataset - be it the 1st one or the second to
last. Just use reload with the appropriate parameter

Michael Feingold, President
401 Huehl RD, Suite 2A,
Northbrook, IL 60062
Email: mfeingold@hill30.com
Web: hill30.com http://www.hill30.com

On Tue, Oct 4, 2016 at 12:01 PM, subhash-periasamy <notifications@github.com

wrote:

Hi @mfeingold https://github.com/mfeingold,
I guess we have a disconnect here. Since @dhilt https://github.com/dhilt's
suggestion is to look into cache within datasource, I am afraid if that
might help since the data changes more frequently and the ui is talking to
a backend table with million rows.

I don;t understand how reload will help me. Sorry if I am missing anything
obvious.

Thanks!


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#120 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIS36SIyPl_KFew0oNgYOHeYAL05thqks5qwoZYgaJpZM4KNF0N
.

dhilt commented

This is a popular topic... look at #31

Thanks for digging through the old threads. Currently I am planning to queue the incoming requests in the datasource and execute only last n requests (may be 2 or 3). This would solve my issue. Need to play around a little bit to determine n. I will keep you posted on how it goes.

Also I will see if there is a way to get this done within ui-scroll. Thanks for your help!

I was able to solve this problem by doing the following.
It feels like something that should be built in, but after scrolling through 1000 items and then hitting the home key, I would have to wait ~30 seconds for it to finish the intermediate calls and render.

Hopefully this helps someone.

var last_descriptor = null;

$scope.datasource = {
    get: function(descriptor, success) {

        var result = $scope.filteredDomains.slice(Math.max(descriptor.index, 0), descriptor.index + descriptor.count);
        success(result);

        last_descriptor = descriptor;

        last_descriptor.position = $window.pageYOffset;

    }
};

// When scrolling up a lot, check number of items we are transitioning and "reload" if necessary
$scope.check_for_reload = function() {

    if (!last_descriptor) {
        return;
    }

    var new_first_item = -1;
    var max_loaded = last_descriptor.index + last_descriptor.count;

    if ($window.pageYOffset === 0) {
        // reset to zero
        new_first_item = 0;
    } else {

        var position = $window.pageYOffset;
        var perc_scrolled = last_descriptor.position / position;

        new_first_item = max_loaded * perc_scrolled;

    }

    // If we are skipping more than "n" items, reload
    if (max_loaded - new_first_item > 200) {
        $scope.uiScrollAdapter.reload(new_first_item);
    }


};

angular.element($window).bind("scroll", $scope.check_for_reload);
dhilt commented

@dustin-s I guess, your solution can be improved by min/max indexes manipulation to keep scroll bar params consistent after reload (https://rawgit.com/angular-ui/ui-scroll/master/demo/userIndexes/userIndexes.html). Do you have a plunker or something like plunker (https://plnkr.co/yNpY0K) for your code? I could such an improvement or even make an official demo...

Seems like a good idea. Unfortunately it might break if the height of the item varies

I've created a plunkr as you suggested.

https://plnkr.co/Q33Hj7

Would debouncing scroll events be useful here? Seems like you should be able to tell which items need to be displayed and you can render them without having to perform the intermediate fetch/render/clip work.