Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a reverse infinite scroll using ngInfiniteScroll directive in AngularJS

I would like to use the ngInfiniteScroll directive from here: http://binarymuse.github.io/ngInfiniteScroll/ in my angular js app to implement a reverse infinite scroll (like in a chat widget). However the documentation for this directive does not seem to mention how this can be accomplished. It only documents how the standard infinite scroll is implemented. Could someone guide me in this regards? Thanks!

P.S : I'm keen on using this directive since it deals with the DOM control; the standard infinite scroll directive from angular keeps creating DOM elements as I scroll which is never deleted.

like image 801
Amal Antony Avatar asked Nov 12 '13 12:11

Amal Antony


People also ask

How infinite scroll is implemented in AngularJS?

ngInfiniteScroll is a directive that you can use to implement infinite scrolling in your AngularJS applications. Simply declare which function to call when the user gets close to the bottom of the content with the directive and the module will take care of the rest.

How is infinite scroll implemented?

Infinite scrolling will require two key parts. One part will be a check for the window scroll position and the height of the window to determine if a user has reached the bottom of the page. Another part will be handling the request for additional information to display.

How do you implement infinite scroll in backend?

Setting up backend First create a new Node project. Open up your terminal and create a new project folder. Install the dependencies, we need express module for now. Now we have a back end simulation ready which will keep on giving us data for any page number and any page size request.


2 Answers

I think you should rather have a model based approach (which fits particularly to angular) ie when you scroll up and reach a limit, you load more data and insert them at the beginning of your messages collection (you could also remove the most recent if you want to limit the amount of html nodes loaded for performance reason).

This is the kind of approach I have used with lrInfiniteScroll

There is no dom manipulation at all, it just detects when you scroll down and reach the bottom (with a debounce) and trigger an handler you have bound so you can do whatever you want, and particularly change your model: your application remains model driven

I have change the logic a bit to have the scroll up behavior, but the idea remain the same

(function (ng) {
'use strict';
var module = ng.module('lrInfiniteScroll', []);

module.directive('lrInfiniteScroll', ['$timeout', function (timeout) {
    return{
        link: function (scope, element, attr) {
            var
                lengthThreshold = attr.scrollThreshold || 50,
                timeThreshold = attr.timeThreshold || 400,
                handler = scope.$eval(attr.lrInfiniteScroll),
                promise = null,
                lastScrolled = -9999;

            lengthThreshold = parseInt(lengthThreshold, 10);
            timeThreshold = parseInt(timeThreshold, 10);

            if (!handler || !ng.isFunction(handler)) {
                handler = ng.noop;
            }

            element.bind('scroll', function () {

                var scrolled = element[0].scrollTop;
                //if we have reached the threshold and we scroll up
                if (scrolled < lengthThreshold && (scrolled - lastScrolled) < 0) {
                    //if there is already a timer running which has no expired yet we have to cancel it and restart the timer
                    if (promise !== null) {
                        timeout.cancel(promise);
                    }
                    promise = timeout(function () {
                        handler();
                        //scroll a bit againg
                        element[0].scrollTop=element[0].clientHeight/2;
                        promise = null;
                    }, timeThreshold);
                }
                lastScrolled = scrolled;
            });


            //scroll first to the bottom (with a delay so the elements are rendered)
            timeout(function(){
                element[0].scrollTop=element[0].clientHeight;
            },0);
        }

    };
}]);
})(angular);

And a running example

like image 75
laurent Avatar answered Oct 18 '22 19:10

laurent


you can use this zInfiniteScroll project on github, it make you scroll down to end or scroll up to top for update feeds.

if you want to add auto scroll down when received message, bind this ngSmoothScroll project

here is use example:

<body ng-app="myApp" ng-controller="mainCtrl">
    <div z-infinite-scroll="loadOlder" inverse="false" body-scroll="true">
        <div smooth-scroll scroll-if="{{$last}}" duration="0" ng-repeat="obj in messages">
{{obj.message}}
        </div>
    </div>
</body>

this is demo for you from plunker

it will received message 10 seconds, and if you scroll to top that history will be loaded.

like image 40
Zam Avatar answered Oct 18 '22 18:10

Zam