0

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.

3 Answers 3

3

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>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. This works great. Any thoughts on the performance implications of a $watch being created?
1

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...

3 Comments

I don't think I've ever seen $emit being used inside a filter. How is this done?
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); } })
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?).
0

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();
      }
    }
);

Comments

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.