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"유지를 시작해야합니다. limit은 현재 페이지를 유지 관리하는 방법과는 별도로 페이지에 레코드 수만 제공합니다. startIndex를 유지하여 수행 할 수 있습니다.
Rutesh Makhijani

레코드 수가 많지 않습니다. 내가하고 싶은 것은 이미 가지고있는 컨트롤러 (PhoneListCtrl)를 사용하는 것입니다. 서버인지 클라이언트인지 모르겠습니다. 죄송합니다!
Tomarto

1
@RuteshMakhijani 많은 수의 레코드와 비슷한 요구 사항이 있습니다. 많은 수의 레코드에 서버 쪽 페이지 매김을 사용하는 이유를 설명하십시오.
Dinesh PR

답변:


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

괄호를 추가하고 위키에서 업데이트했습니다. 그러나 그것들없이 작동해야합니다.
Andrew Joslin

1
오! 신경 쓰지 마. if (input?)반품하기 전에 조건을 추가합니다 input.slice(start). 앤디 감사합니다!
zx1986

1
Bart와 마찬가지로 페이징 정보를 호출 함수에 전달하여 페이징 가능한 데이터를 가져와야했습니다. 이는 비슷하지만 다르며 경우에 따라 도움이 될 수 있습니다. plnkr.co/edit/RcSso3verGtXwToilJ5a
Steve Black

3
안녕하세요,이 데모는 제가 참여한 프로젝트에 매우 유용했습니다. 모두를 보거나 페이지 매김을 토글하고 각 페이지를 표시하는 옵션을 추가해야했습니다. 그래서 데모를 확장했습니다. 고마워 jsfiddle.net/juanmendez/m4dn2xrv
Juan Mendez

39

방금 Twitter Bootstrap 코드로 빌드를 사용하여 각 열에서 페이지 매김 + 검색 + 순서를 보여주는 JSFiddle을 만들었습니다 : http://jsfiddle.net/SAWsA/11/


2
대단한 직업. 한 단계 더 나아가서 열 표제를 동적으로 만드는 것이 좋습니다. 즉, 항목 json 배열에서 모든 고유 키 값을 가져 와서 값을 하드 코딩하는 대신 ng-repeat에 바인딩하십시오. 내가 여기에서 한 것과 비슷한 것 : jsfiddle.net/gavinfoley/t39ZP
GFoley83

- 컨트롤러의 코드는 그냥 덜 재사용 할 수있는 모든 것을 가진 telerik.com/help/silverlight/...가 QueryableDomainServiceCollectionView, VirtualQueryableCollectionView, HierarchicalDataCollectionView : 누락 된 각도 보인다
르블랑 메네

1
이것은 정말 훌륭한 솔루션이며 적응하기 쉽습니다. 두 개의 바인딩 된 요소의 양이 수천에 도달 한 복잡한 시나리오에서 사용되었으며 실제로 전체 코드를 리팩터링하는 옵션이 아니 었습니다. 기본 원칙을 설명하는 코드로 답변을 업데이트해야합니다. 그리고 아마도 바이올린에서 AngularJS와 Bootstrap 버전을 업그레이드하십시오 :)
davidkonrad

15

메모리 내 페이지 매김을 매우 간단하게 만드는 모듈을 만들었습니다.

그것은 단순히 대체하여 쪽수를 매기다을 수행 할 수 있습니다 ng-repeat와 함께 dir-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 : 분리 된 dirPagination.tpl.html 대신 <dir-pagination-controls> <ul class = "pagination"ng-if = "1 <pages.length ||! autoHide"> 안에 페이지 매김 코드를 포함시킬 수도 있습니다. .. </ ul> </ dir-pagination-controls>
npcoder

5

이 스레드가 오래되었다는 것을 알고 있지만 업데이트를 유지하기 위해 응답하고 있습니다.

Angular 1.4 이상 에서는 매개 변수를 수락하는 것 외에도 매개 변수를 허용하는 limitTo 필터를 직접 사용할 수 있습니다 .limitbegin

용법: {{ limitTo_expression | limitTo : limit : begin}}

따라서 이제 페이지 매김과 같은 것을 달성하기 위해 타사 라이브러리를 사용할 필요가 없습니다. 나는 같은 것을 설명하기 바이올린 을 .


연결 한 바이올린은 실제로 begin 매개 변수를 사용하지 않습니다.
Brawny Man

3

이 지시어를 확인하십시오 : https://github.com/samu/angular-table

정렬 및 페이지 매김을 많이 자동화하고 원하는대로 테이블 / 목록을 사용자 정의 할 수있는 충분한 자유를 제공합니다.


언뜻보기에 이것은 내가 필요로하는 것과 정확히 같았 지 만 $ / resource로 작동시킬 수는 없습니다. 항상 내 목록이 비어 있다고 생각합니다. github.com/ssmm/angular-table/blob/master/coffee/… ... 아직 이유를 알 수 없었습니다. : /
Mike Desjardins

사용할 수없고 $index배열에 증분 값이 포함되어 있지 않으므로 첫 번째 열에 Sno를 표시하는 방법
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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.