1

I coded the below directive for infinite scroll, my problem which I couldn't figure out why it just fire once when the directive is loaded, I need your advice on how to make my list infinite-scroll.

I'm using it to get data remotely and each time i'm calling it I add to the counter 25, so each time it would return more data.

Thanx,

angular.module('MyApp')
  .controller('InboxCtrl', function($scope, InboxFactory) {

    var counter = 0;

    $scope.loadData = function() {
      var promise = InboxFactory.getEvents(counter);
      promise.then(function(result) {
        $scope.events = result;
      });
      counter += 25;
    };

  });

angular.module('MyApp')
  .factory('InboxFactory', function($http, $q) {
    // Service logic

    var defered = $q.defer();

    function getUrl(count) {
      return "api/inbox/get?request={'what':'Search','criteria':'inbox','criteriaId':null,'startTime':null,'endTime':null,'offset':" + count + ",'limit':25,'order':'event_time','direction':'DESC','source':''}";
    }

    function extract(result) {
      return result.data.data;
    }

    // Public API here
    return {
      getEvents: function(count) {
        $http.get(getUrl(count)).then(
          function(result) {
            defered.resolve(extract(result))
          }, function(err) {
            defered.reject(err);
          }
        );

        return defered.promise;
      }
    };
  });

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

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

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

          element.bind('scroll', function() {
            var
              remaining = element[0].scrollHeight - (element[0].clientHeight + element[0].scrollTop);

            //if we have reached the threshold and we scroll down
            if (remaining < lengthThreshold && (remaining - lastRemaining) < 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();
                promise = null;
              }, timeThreshold);
            }
            lastRemaining = remaining;
          });
        }

      };
    }
  ]);
<ul class="inbox-list" infinite-scroll="loadData()">
  <li class="clearfix" ng-repeat="event in events">{{event}}</li>
</ul>

1 Answer 1

1

I Made some changes the more important is the use of ng-transclude and the creation of a new scope for the directive to pass the method and the parameters. You can have a look at the jsbind. Of course the data are hard coded so i could fake the behaviour.

<ul class="inbox-list" my-infinite-scroll composite-method="loadData()">
Sign up to request clarification or add additional context in comments.

1 Comment

i changed Array.concat($scope.events, result); to [].concat($scope.events, result);. it is working on firefox and chrome. Before was working just in firefox

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.