Non
Non

Reputation: 8589

How to combine ion-refresher and ion-infinite-scroll?

I have this so far and it is working horrible, everytime I go to the bottom of the page, it reloads and throw me back to the top

  <ion-content>
    <ion-refresher
      on-refresh="doRefresh()">
    </ion-refresher>
    <div ng-repeat="post in posts">
      <a ng-href="#/tabs/news/{{post.site_ID}}/{{post.ID}}">
        <h2 ng-bind-html="post.title"></h2>
        <p>{{:: post.date | date}}</p>
      </a>
    </div>
    <ion-infinite-scroll
            on-infinite="loadMore()"
            distance="1%">
     </ion-infinite-scroll>
  </ion-content>

and the controller

.controller('NewsCtrl', function($scope, $ionicLoading,
                                 $stateParams, FreshlyPressed) {

  $scope.posts = [];

  $scope.loadMore = function() {
    $scope.posts = FreshlyPressed.getBlogs($scope);
    $scope.$broadcast('scroll.infiniteScrollComplete');
  },

  $scope.doRefresh = function() {
    $scope.posts = FreshlyPressed.getBlogs($scope);
    $scope.$broadcast('scroll.refreshComplete');
  }
  $scope.doRefresh();

});

Upvotes: 4

Views: 1906

Answers (1)

m59
m59

Reputation: 43785

It looks like the problem is that you're broadcasting infinteScrollComplete and refreshComplete before they are actually completed. Those appear to be asynchronous requests, but you're responding as though they are synchronous.

This is what is really happening:

$scope.posts = FreshlyPress.getBlogs($scope); // call goes out
$scope.$broadcast(etc); // call is still out, this is too early

// (call comes back at a variable time, $broadcast needs to occur at that time)

To handle this, you need either a callback or a promise, depending on the api of your getBlogs function. It looks like getBlogs is doing a bit of magic to either add its result to $scope internally or it returns an empty array/object and then populates it when the result comes in. Either way, that is breaking the Single Responsibility Principle. getBlogs should just return the data in a callback/promise and let the controller decide would to do with that data.

var limit = 10; // max results
var offset = 0; // starting index
$scope.posts = []; // add results here as they come in
$scope.loadMore = function() {
  FreshlyPressed.getBlogs(limit, offset).then(function(results) {
    $scope.posts = $scope.posts.concat(results); // add results
    offset = $scope.posts.length; // adjust offset for next query
    $scope.$broadcast('scroll.infiniteScrollComplete');
  });
}; // <-- you also had a comma here

For the refresh, you would just reset the state:

$scope.posts = []; // empty results
offset = 0; // start back at first post

And now you can load more posts just like before.

Upvotes: 0

Related Questions