Ionic infinite scroll
ion-infinite-scroll
works with some sort of paginated result and you seem to feed your list with all the results.
Your API should look something like this:
http://www.examplesite.com/tna_wp/wp-json/posts?filter[category_name]=international&filter[posts_per_page]=2&filter[page]=1
notice I've added a page filter.
and your service responsible to fetch the data should look something like this:
.factory('dataService', function($http) { return { GetPosts: function(page, pageSize) { return $http.get("http://mywebservice/api/test/posts/" + page + "/" + pageSize); } };});
Your controller
.controller('mainController', function($scope, dataService) { $scope.posts = []; $scope.theEnd = false; var page = 0; var pageSize = 10; $scope.$on('$stateChangeSuccess', function() { $scope.loadMore(); }); $scope.loadMore = function(argument) { page++; dataService.GetPosts(page, pageSize) .then(function(result) { console.log('items fetched: ' + result.data.length); if (result.data.length > 0) { angular.forEach(result.data, function(value, key) { $scope.posts.push(value); }); } else { $scope.theEnd = true; } }) .finally(function() { $scope.$broadcast("scroll.infiniteScrollComplete"); }); };})
would initialize an array of objetct - as you're doing - and a boolean which tells the directive ion-infinite-scroll
when you've reached the end:
$scope.posts = [];$scope.theEnd = false;
Then you can have some variables to control the pagination:
var page = 0;var pageSize = 10;
I start loading when the view is loaded:
$scope.$on('$stateChangeSuccess', function() { $scope.loadMore();});
$scope.loadMore
then would increment the page number:
page++;
and call the service layer:
dataService.GetPosts(page, pageSize)
when I've reached the end of the stream I would set the variable:
$scope.theEnd = true;
to let the directive know we don't have other items to append.
.finally(function() { $scope.$broadcast("scroll.infiniteScrollComplete");});
finally
is always called when the promise is resolved.
Instead of ng-repeat
you can use collection-repeat which should be much faster.
You can play with it here.
Try this create a function infiniteScrollCompleteCancelLoadMore
and call it when you want to complete the scroll and you have reached the end of your list.
function infiniteScrollCompleteCancelLoadMore() { $timeout(function () { $timeout(function () { $scope.$broadcast('scroll.infiniteScrollComplete'); $rootScope.canLoad = false; }); }); }$scope.loadMore = function() { Worlds.GetNewPosts().then(function (worlds){ var loadedIdss = _.pluck($scope.worlds, 'id'); var newItemss = _.reject(worlds, function (item){ return _.contains(loadedIdss, item.id); }); $scope.worlds = newItemss.concat($scope.worlds); infiniteScrollCompleteCancelLoadMore() // CHANGE HERE });};
and your HTML
<ion-infinite-scroll on-infinite="loadMore()" ng-if="canLoad" distance="1%" immediate-check="false"></ion-infinite-scroll>
OR call This is you just want to cancel loadMore loop
.
function infiniteScrollComplete() { $timeout(function () { $timeout(function () { $scope.$broadcast('scroll.infiniteScrollComplete'); }); }); }