使用ng-repeat在列表上分页


130

我正在尝试将页面添加到我的列表中。我遵循了有关智能手机的AngularJS教程,我试图仅显示一定数量的对象。这是我的html文件:

  <div class='container-fluid'>
    <div class='row-fluid'>
        <div class='span2'>
            Search: <input ng-model='searchBar'>
            Sort by: 
            <select ng-model='orderProp'>
                <option value='name'>Alphabetical</option>
                <option value='age'>Newest</option>
            </select>
            You selected the phones to be ordered by: {{orderProp}}
        </div>

        <div class='span10'>
          <select ng-model='limit'>
            <option value='5'>Show 5 per page</option>
            <option value='10'>Show 10 per page</option>
            <option value='15'>Show 15 per page</option>
            <option value='20'>Show 20 per page</option>
          </select>
          <ul class='phones'>
            <li class='thumbnail' ng-repeat='phone in phones | filter:searchBar | orderBy:orderProp | limitTo:limit'>
                <a href='#/phones/{{phone.id}}' class='thumb'><img ng-src='{{phone.imageUrl}}'></a>
                <a href='#/phones/{{phone.id}}'>{{phone.name}}</a>
                <p>{{phone.snippet}}</p>
            </li>
          </ul>
        </div>
    </div>
  </div>

我添加了带有某些值的select标记,以限制将要显示的项目数。我现在想要的是添加分页以显示下一个5、10等。

我有一个与此相关的控制器:

function PhoneListCtrl($scope, Phone){
    $scope.phones = Phone.query();
    $scope.orderProp = 'age';
    $scope.limit = 5;
}

我也有一个模块,以便从json文件中检索数据。

angular.module('phonecatServices', ['ngResource']).
    factory('Phone', function($resource){
        return $resource('phones/:phoneId.json', {}, {
            query: {method: 'GET', params:{phoneId:'phones'}, isArray:true}
        });
    });

1
当您说要实现下一页和上一页时,您是否希望分页完全在客户端或服务器端进行。如果记录数太多,则应选择服务器端分页。在任何情况下,您都需要开始维护“ startIndex”-限制将仅提供页面上的记录数,此外,您还需要一些维护当前页面的方式-这可以通过维护startIndex来完成。
Rutesh Makhijani 2012年

我没有很多记录。我想要做的是使用已经拥有的控制器(PhoneListCtrl)。我不知道这是服务器端还是客户端。抱歉!
Tomarto 2012年

1
@RuteshMakhijani我对大量记录有类似的要求,请解释对大量记录使用服务器端分页的原因
Dinesh PR

Answers:


215

如果您没有太多数据,则可以通过将所有数据存储在浏览器中并过滤在特定时间可见的内容来进行分页。

这是一个简单的分页示例:http : //jsfiddle.net/2ZzZB/56/

该示例在angular.js github Wiki上的小提琴列表中,应该会有所帮助:https : //github.com/angular/angular.js/wiki/JsFiddle-Examples

编辑:http : //jsfiddle.net/2ZzZB/16/http://jsfiddle.net/2ZzZB/56/(如果有45个结果,则不会显示“ 1 / 4.5”)


1
非常感谢你!这正是我想要的。我之前看过这个例子,但是没有用。现在我注意到有一点语法错误。“ for”句子后缺少方括号。
Tomarto 2012年

我添加了括号并在Wiki上对其进行了更新。但是没有他们,它应该可以工作。
安德鲁·乔斯林

1
哦!没关系。我if (input?)在退货前加了条件input.slice(start),谢谢安迪!
zx1986

1
像Bart一样,我需要将分页信息传递给调用函数以获取可分页的数据-相似但有所不同,在某些情况下可能会有所帮助。plnkr.co/edit/RcSso3verGtXwToilJ5a
史蒂夫·布莱克

3
嗨,这个演示非常方便我参与的一个项目。我需要添加选项以查看全部或切换分页以及显示每个页面。因此,我扩展了演示。非常感谢。jsfiddle.net/juanmendez/m4dn2xrv
Juan Mendez

39

我刚刚制作了一个JSFiddle,使用带有Twitter Bootstrap代码的Build在每列上显示分页+搜索+按顺序排列 :http : //jsfiddle.net/SAWsA/11/


2
好工作。最好进一步采取行动,使列标题具有动态性,即从项json数组获取所有唯一键值,并将其绑定到ng-repeat,而不是对值进行硬编码。类似于我在这里所做的事情:jsfiddle.net/gavinfoley/t39ZP
GFoley83

在控制器中拥有所有代码只会降低它的可重用性-telerik.com/help/silverlight/… 似乎缺少角度:QueryableDomainServiceCollectionView,VirtualQueryableCollectionView,HierarchicalDataCollectionView
Leblanc Meneses

1
这是一个非常好的解决方案,易于调整。在复杂的场景中使用它,其中两个绑定元素的数量达到了数千个,并且实际上不是重构整个代码的选择。您应该使用一些解释基本原理的代码来更新答案。也许在小提琴中升级AngularJS和Bootstrap版本:)
davidkonrad

15

我建立了一个模块,使内存分页非常简单。

它可以让您简单地进行分页,只需将替换ng-repeatdir-paginate,将每页的项目指定为管道式过滤器,然后将控制以任意位置以单个指令的形式放置在任意位置,<dir-pagination-controls>

以Tomarto提出的原始示例为例:

<ul class='phones'>
    <li class='thumbnail' dir-paginate='phone in phones | filter:searchBar | orderBy:orderProp | limitTo:limit | itemsPerPage: limit'>
            <a href='#/phones/{{phone.id}}' class='thumb'><img ng-src='{{phone.imageUrl}}'></a>
            <a href='#/phones/{{phone.id}}'>{{phone.name}}</a>
            <p>{{phone.snippet}}</p>
    </li>
</ul>

<dir-pagination-controls></dir-pagination-controls>

控制器中不需要任何特殊的分页代码。全部由模块内部处理。

演示:http//plnkr.co/edit/Wtkv71LIqUR4OhzhgpqL?p = preview

资料来源:GitHub的dirPagination


JFI:我们也可以在<dir-pagination-controls> <ul class =“ pagination” ng-if =“ 1 <pages.length ||!autoHide”>中包含分页代码,而不是将dirPagination.tpl.html分开。 .. </ ul> </ dir-pagination-controls>
npcoder

5

我知道这个线程现在已经很旧了,但我正在回答这个问题,以使事情有所更新。

在Angular 1.4及更高版本中,您可以直接使用limitTo过滤器,该过滤器除了接受limit参数外还接受begin参数。

用法: {{ limitTo_expression | limitTo : limit : begin}}

因此,现在您可能无需使用任何第三方库来实现诸如分页之类的功能。我创建了一个小提琴来说明这一点。


您链接到的小提琴实际上并未使用begin参数。
壮汉

3

查看此指令:https : //github.com/samu/angular-table

它可以自动执行很多排序和分页,并为您提供了足够的自由度来自定义表格/列表。


乍一看,这似乎正是我所需要的,但是我似乎无法通过$ resource使它工作。似乎总是认为我的清单在这里是空的:github.com/ssmm/angular-table/blob/master/coffee / ... ...尚无法弄清原因。:/
Mike Desjardins

如何在第一列中显示Sno,因为我无法使用$index并且数组不包含增量值
Dwigh

我是这样<td at-sortable at-attribute="index">{{sortedAndPaginatedList.indexOf(item) + 1}}</td>做的:但是我不知道这是不是正确的方法
Dwigh

2

这是一个演示代码,其中有分页+ AngularJS过滤:

https://codepen.io/lamjaguar/pen/yOrVym

JS:

var app=angular.module('myApp', []);

// alternate - https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
// alternate - http://fdietz.github.io/recipes-with-angular-js/common-user-interface-patterns/paginating-through-client-side-data.html

app.controller('MyCtrl', ['$scope', '$filter', function ($scope, $filter) {
    $scope.currentPage = 0;
    $scope.pageSize = 10;
    $scope.data = [];
    $scope.q = '';

    $scope.getData = function () {
      // needed for the pagination calc
      // https://docs.angularjs.org/api/ng/filter/filter
      return $filter('filter')($scope.data, $scope.q)
     /* 
       // manual filter
       // if u used this, remove the filter from html, remove above line and replace data with getData()

        var arr = [];
        if($scope.q == '') {
            arr = $scope.data;
        } else {
            for(var ea in $scope.data) {
                if($scope.data[ea].indexOf($scope.q) > -1) {
                    arr.push( $scope.data[ea] );
                }
            }
        }
        return arr;
       */
    }

    $scope.numberOfPages=function(){
        return Math.ceil($scope.getData().length/$scope.pageSize);                
    }

    for (var i=0; i<65; i++) {
        $scope.data.push("Item "+i);
    }
  // A watch to bring us back to the 
  // first pagination after each 
  // filtering
$scope.$watch('q', function(newValue,oldValue){             if(oldValue!=newValue){
      $scope.currentPage = 0;
  }
},true);
}]);

//We already have a limitTo filter built-in to angular,
//let's make a startFrom filter
app.filter('startFrom', function() {
    return function(input, start) {
        start = +start; //parse to int
        return input.slice(start);
    }
});

HTML:

<div ng-app="myApp" ng-controller="MyCtrl">
  <input ng-model="q" id="search" class="form-control" placeholder="Filter text">
  <select ng-model="pageSize" id="pageSize" class="form-control">
        <option value="5">5</option>
        <option value="10">10</option>
        <option value="15">15</option>
        <option value="20">20</option>
     </select>
  <ul>
    <li ng-repeat="item in data | filter:q | startFrom:currentPage*pageSize | limitTo:pageSize">
      {{item}}
    </li>
  </ul>
  <button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">
        Previous
    </button> {{currentPage+1}}/{{numberOfPages()}}
  <button ng-disabled="currentPage >= getData().length/pageSize - 1" ng-click="currentPage=currentPage+1">
        Next
    </button>
</div>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.