Join the Stack Overflow Community
Stack Overflow is a community of 6.3 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I'm paginating an Angular table and want to display all the page numbers beneath the table.

I'm planning to create an array of the page numbers and then use ng-repeat to display them all:

HTML

<tr ng-repeat-start="item in c.filteredList = (c.data | dynamicFilter:c.filter | orderBy:c.sortOrder.order:c.sortOrder.reverse)">

JS

    this.checkPage = function(){
      this.pageNumArr = [];

      for(i=0; i<this.filteredList.length/this.perPage; i++){
        this.pageNumArr.push(i);
      }
    }

Where this.perPage is the number of items per page (set by the user).

What I can't figure out is how to trigger checkPage() whenever the filter changes.

share|improve this question
up vote 3 down vote accepted

You would be best binding your page number ng-repeat to a function that creates and returns the array of page numbers. This will create a watcher for the function and keep the array of page numbers up to date.

There will be no need to manually create a $watch in your controller.

 this.pageNumbers= function(){
      var pageNumArr = [];

      for(i=0; i<this.filteredList.length/this.perPage; i++){
        pageNumArr.push(i);
      }
      return pageNumArr

    }

<span ng-repeat="page in c.pageNumbers()">{{page}}</span>
share|improve this answer
    
Thanks. This works great. Any thoughts on the performance implications of a $watch being created? – ibhhvc Jan 29 at 18:36

I think that triggering events inside a filters shouldn't be considered a best practice, probably, you need to find another approach.

By the way, there are many way:

  1. If you can edit that filter, simply, pass the $scope reference to it and trigger the event via $scope.emit or $scope.broadcast: <li ng-repeat="item in items | myFilter:[param1, param2, paramN]"></li>

  2. Angular supports filter inside a controller, so, probably this should be a better solution https://toddmotto.com/everything-about-custom-filters-in-angular-js/ (have a look at Filter 4: Controller/$scope filter);

  3. Register a watcher on your model, but, this is bad for performances...

share|improve this answer
    
I don't think I've ever seen $emit being used inside a filter. How is this done? – ibhhvc Jan 29 at 18:41
    
And yes, this is a custom filter: app.filter('paginate', function(){ return function(input, perPage, pageNum){ var startRow = perPage*(pageNum-1); var endRow = startRow + perPage return input.slice(startRow, endRow); } }) – ibhhvc Jan 29 at 18:42
    
I think that @Pascal Winter exposed correctly what you are looking for, the best solution is to bind, through a filter, the paginator to the current page list. By the way, as you pass pageNum and perPage, you can pass even $scopeor one its property (a function?). – Hitmands Jan 29 at 19:35

You can watch for the filteredList and call the checkPage() there:

var self = this;
$scope.$watch(
    function() {
      return self.filteredList.length;
    },
    function(newValue, oldValue) {
      if (newValue !== oldValue) {
        self.checkPage();
      }
    }
);
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.