Pagination With Angular

Few days ago i talked about infinite scroll but this was not really usefull without pagination so today we will see how to do some pagination using a Service like for the geolocalisation.

Let’s start now!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
App.service "Pagination", ->

  @paginate = ($scope, @resource, @maxElemPerPage=20, @onNewPage, @query={}) ->
    @page = 1
    @canLoadNextPage = true
    $scope.loadPage = (promise) =>
      return promise.resolve() unless @canLoadNextPage
      @load promise

    @load = (promise) =>
      @canLoadNextPage = false
      q = angular.extend @query, page: @page
      @resource.query q, (resources) =>
        @canLoadNextPage = true if resources.length is @maxElemPerPage
        @page++
        @onNewPage resources if @onNewPage
        promise.resolve() if promise

    @load()

  @
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
App.service("Pagination", function() {
  this.paginate = function($scope, resource, maxElemPerPage, onNewPage, query) {
    var _this = this;
    this.resource = resource;
    this.maxElemPerPage = maxElemPerPage != null ? maxElemPerPage : 20;
    this.onNewPage = onNewPage;
    this.query = query != null ? query : {};
    this.page = 1;
    this.canLoadNextPage = true;
    $scope.loadPage = function(promise) {
      if (!_this.canLoadNextPage) {
        return promise.resolve();
      }
      return _this.load(promise);
    };
    this.load = function(promise) {
      var q;
      _this.canLoadNextPage = false;
      q = angular.extend(_this.query, {
        page: _this.page
      });
      return _this.resource.query(q, function(resources) {
        if (resources.length === _this.maxElemPerPage) {
          _this.canLoadNextPage = true;
        }
        _this.page++;
        if (_this.onNewPage) {
          _this.onNewPage(resources);
        }
        if (promise) {
          return promise.resolve();
        }
      });
    };
    return this.load();
  };
  return this;
});
Toggle coffeescript/javascript

This service contains only one method paginate.

This method will add the loadPage function to your scope and finally load the first page. Everytime loadPage function is call, it will load the next page.

That’s all, now we just need to initialize our controller to say which data we want to paginate.

1
2
3
4
App.controller "MyModelsIndexCtrl", ($scope, @MyModel, @Pagination) ->
  $scope.myModels = []
  Pagination.paginate $scope, MyModel, 10, (myModels) ->
    $scope.myModels.push myModel for myModel in myModels
1
2
3
4
5
6
7
8
9
10
11
12
13
14
App.controller("MyModelsIndexCtrl", function($scope, MyModel, Pagination) {
  this.MyModel = MyModel;
  this.Pagination = Pagination;
  $scope.myModels = [];
  return Pagination.paginate($scope, MyModel, 10, function(myModels) {
    var myModel, _i, _len, _results;
    _results = [];
    for (_i = 0, _len = myModels.length; _i < _len; _i++) {
      myModel = myModels[_i];
      _results.push($scope.myModels.push(myModel));
    }
    return _results;
  });
});
Toggle coffeescript/javascript

and because you can add a query you are also able to paginate following this query like that

1
2
3
4
5
...
    Pagination.paginate $scope, MyModel, 10, (myModels) ->
      $scope.myModels.push myModel for myModel in myModels
    , q: { user_id_eq: 10, id_neq: $scope.myModel.id } # you can write what you want
...

Finally, if you use the infinite scroll from here you just need in your view to have something like that

1
2
3
<div infinite-scroll="loadPage">
  <div ng-repeat="myModel in myModels"></div>
</div>

and you will have automatic pagination without anything else.

Comments

Copyright © 2014 - Anthony Estebe -