用AngularJS创建分页(转自前端乱炖

在编写普通网页或者web应用时,一个最普遍的需求就是创建分页。分页这个词乍一听上去可能有些陌生,但是你肯定每天都在用,它就是你在浏览新闻时最下边显示你已经看到第几页,同时跳转到具体某一页,首页或者末页的那个东西。这个当然不是什么很难的需求,实现它的方式多种多样,从前端到后端都可以有具体的实现方法。借助AngularJS,你可以使用几个简单的指令和过滤器(filter)来实现它。

我们下面先来看代码,然后再来讲述其中的一些关键点:

<div ng-controller="PaginationCtrl"> 
    <table class="table table-striped">
        <thead> 
             <tr>
                 <th>Id</th>
                 <th>Name</th>
                 <th>Description</th> 
             </tr>
        </thead>
        <tbody>
         <tr ng-repeat="item in items | offset: currentPage*itemsPerPage | limitTo: itemsPerPage">             <td>`item`.`id`</td> 
             <td>`item`.`name`</td>
              <td>`item`.`description`</td>
          </tr> 
          </tbody>
          <tfoot>
              <td colspan="3">
              <div class="pagination"> 
                  <ul>
                      <li ng-class="prevPageDisabled()"><a href ng-click="prevPage()">  Prev</a>
                      </li>
                      <li ng-repeat="n in range()"ng-class="{active: n == currentPage}"                                     ng-click="setPage(n)">
                          <a href="#">{{n+1}}</a> 
                      </li>
                      <li ng-class="nextPageDisabled()"><a href ng-click="nextPage()">Next </a>
                      </li> 
                  </ul>
              </div> 
              </td>
          </tfoot>
       </table>
</div>

上面的代码很好理解,我们看到我们首先使用ng-controller声明了一个控制器PaginationCtrl,然后在其中还是用了ng-class,ng-click指令,ng-click指令很好理解,绑定了它的DOM元素一旦被点击就会执行scope中的一串代码,一般来说是执行一个函数。而ng-class则会实时更新绑定了它的DOM元素的类。还有一点需要注意的是我们再次使用了一个叫做offset的过滤器,它的作用是截取需要显示的条目,它带有一个参数,我们将在后面具体看到它的实现方式。

app.filter('offset', function() { 
    return function(input, start) {
        start = parseInt(start, 10);
        return input.slice(start); 
        };
  });

如果你不太记得AngularJS中的过滤器怎么写,我们现在就来简单的复习一下。AngularJS的过滤器需要返回一个函数,这个函数接收至少一个参数,它的第一个参数是需要过滤的值本身,如果是单个变量,那就是单个变量。如果是在ng-repeat指令中,它指的是整个数组,而不是数组的每一项。在这里,我们的offset是放在ng-repeat中使用的,因此它需要处理的input是整个数组。

下面我们需要定义一个控制器PaginationCtrl来管理实际的$scope.items数组,同时处理启用/禁用分页按钮的逻辑,代码如下:

app.controller("PaginationCtrl", function($scope) {
    $scope.itemsPerPage = 5;
    $scope.currentPage = 0; 
    $scope.items = [];
    for (var i=0; i<50; i++) {
        $scope.items.push({id: i, name: "name "+ i, description: "description " + i });
    }
    $scope.prevPage = function() { 
        if ($scope.currentPage > 0) {
            $scope.currentPage--; 
        }
    };
    $scope.prevPageDisabled = function() {
        return $scope.currentPage === 0 ? "disabled" : "";
    };
    $scope.pageCount = function() {
        return Math.ceil($scope.items.length/$scope.itemsPerPage)-1;
    };
    $scope.nextPage = function() {
        if ($scope.currentPage < $scope.pageCount()) {
            $scope.currentPage++;
         }
    };
   $scope.nextPageDisabled = function() {
        return $scope.currentPage === $scope.pageCount() ? "disabled" : "";
    }

到目前为止,使用AngularJS创建一个分页的代码已经完成了。总结一下,其实分页的思想很简单,首先我们的items是完全载入页面的,其次,我们使用了一个过滤器来将items数组从当前需要显示的第一个项目截断到最后,同时使用AngularJS内建的过滤器limitTo来限制显示的条目。另外,我们在这里还是用了ng-class指令,来启用/禁用第一页和最后一页的按钮。