Làm thế nào để làm phân trang trong AngularJS?


254

Tôi có bộ dữ liệu gồm khoảng 1000 mục trong bộ nhớ và đang cố gắng tạo một máy nhắn tin cho bộ dữ liệu này, nhưng tôi không chắc chắn về cách thực hiện việc này.

Tôi đang sử dụng chức năng lọc tùy chỉnh để lọc kết quả và hoạt động tốt, nhưng bằng cách nào đó tôi cần lấy số lượng trang ra.

Bất kì manh mối nào?


Câu trả lời:


285

Angular UI Bootstrap - Chỉ thị phân trang

Kiểm tra chỉ thị phân trang của UI Bootstrap . Tôi đã kết thúc việc sử dụng nó hơn là những gì được đăng ở đây vì nó có đủ các tính năng cho việc sử dụng hiện tại của tôi và có một thông số kiểm tra kỹ lưỡng để đi kèm với nó.

Lượt xem

<!-- table here -->

<pagination 
  ng-model="currentPage"
  total-items="todos.length"
  max-size="maxSize"  
  boundary-links="true">
</pagination>

<!-- items/page select here if you like -->

Bộ điều khiển

todos.controller("TodoController", function($scope) {
   $scope.filteredTodos = []
  ,$scope.currentPage = 1
  ,$scope.numPerPage = 10
  ,$scope.maxSize = 5;

  $scope.makeTodos = function() {
    $scope.todos = [];
    for (i=1;i<=1000;i++) {
      $scope.todos.push({ text:"todo "+i, done:false});
    }
  };
  $scope.makeTodos(); 

  $scope.$watch("currentPage + numPerPage", function() {
    var begin = (($scope.currentPage - 1) * $scope.numPerPage)
    , end = begin + $scope.numPerPage;

    $scope.filteredTodos = $scope.todos.slice(begin, end);
  });
});

Tôi đã làm một plunker làm việc để tham khảo.


Phiên bản kế thừa:

Lượt xem

<!-- table here -->

<div data-pagination="" data-num-pages="numPages()" 
  data-current-page="currentPage" data-max-size="maxSize"  
  data-boundary-links="true"></div>

<!-- items/page select here if you like -->

Bộ điều khiển

todos.controller("TodoController", function($scope) {
   $scope.filteredTodos = []
  ,$scope.currentPage = 1
  ,$scope.numPerPage = 10
  ,$scope.maxSize = 5;

  $scope.makeTodos = function() {
    $scope.todos = [];
    for (i=1;i<=1000;i++) {
      $scope.todos.push({ text:"todo "+i, done:false});
    }
  };
  $scope.makeTodos(); 

  $scope.numPages = function () {
    return Math.ceil($scope.todos.length / $scope.numPerPage);
  };

  $scope.$watch("currentPage + numPerPage", function() {
    var begin = (($scope.currentPage - 1) * $scope.numPerPage)
    , end = begin + $scope.numPerPage;

    $scope.filteredTodos = $scope.todos.slice(begin, end);
  });
});

Tôi đã làm một plunker làm việc để tham khảo.


2
đẹp và thanh lịch. Nó có thể được cải thiện bằng cách thêm một loại
Carlos Barcelona

3
Thuộc tính num-page không còn cần thiết và chỉ được đọc. Không cần phải vượt qua numPages. Xem các tài liệu: angular-ui.github.io/bootstrap/#/pagination
kvetis

3
GIẢI QUYẾT: các mục trên mỗi trang là thuộc tính cần được đặt trong paginationphần tử.
Bogac

1
^ ^ ^ ^ Đối với tất cả những người đọc mới, hãy xem bình luận của Bogacs: các mục trên mỗi trang hiện đang cần trong phần tử phân trang. Không làm việc mà không có nó.
IfTrue

14
<phân trang> hiện không được dùng nữa. Sử dụng <uib-pagination> thay thế.
mnm

88

Gần đây tôi đã thực hiện phân trang cho trang web Được xây dựng với góc. Bạn chan kiểm tra nguồn: https://github.com/angular/builtwith.angularjs.org

Tôi sẽ tránh sử dụng bộ lọc để tách các trang. Bạn nên chia nhỏ các mục thành các trang trong bộ điều khiển.


61
Giải pháp được trải rộng trên nhiều tập tin. Bạn cần nhìn vào ít nhất là bộ điều khiển và khung nhìn. Tôi không thấy làm thế nào mà bảo đảm một downvote:Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect.
btford

2
Bạn có thể bắt đầu xem <div class = "pagination"> của index.html github.com/angular/builtwith.angularjs.org/blob/master/iêu
Jorge Nunez Newton

6
@btford Tại sao bạn nên tránh sử dụng bộ lọc?
CWSpear

4
Tôi đã bỏ phiếu để chống lại việc bỏ phiếu trước đó vì tôi cảm thấy rằng áp phích cung cấp một ví dụ chất lượng có thể được sử dụng để trả lời câu hỏi ban đầu.
RachelD

1
@btford Vẫn là một ý tưởng tồi khi phân trang bằng bộ lọc? Đây là một plunkr phân trang danh sách thông qua một bộ lọc có vẻ hiệu quả (ít nhất là trong ví dụ tầm thường này lên tới 10 000 000 hàng): embed.plnkr.co/iWxWlCEvd6Uh8erUOyaF
Ryan Kimber

79

Tôi đã phải thực hiện phân trang khá nhiều lần với Angular, và nó luôn là một chút đau đớn cho một cái gì đó mà tôi cảm thấy có thể được đơn giản hóa. Tôi đã sử dụng một số ý tưởng được trình bày ở đây và các nơi khác để tạo ra một mô-đun phân trang khiến việc phân trang trở nên đơn giản như:

<ul>
    <li dir-paginate="item in items | itemsPerPage: 10">{{ item }}</li>
</ul>

// then somewhere else on the page ....

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

Đó là nó. Nó có các tính năng sau:

  • Không có mã tùy chỉnh cần thiết trong bộ điều khiển của bạn để buộc bộ sưu tập itemsvào các liên kết phân trang.
  • Bạn không bị ràng buộc khi sử dụng bảng hoặc chế độ xem lưới - bạn có thể phân trang bất cứ điều gì bạn có thể lặp lại!
  • Đại biểu ng-repeat, vì vậy bạn có thể sử dụng bất kỳ biểu thức nào có thể được sử dụng hợp lệ trong một ng-repeat, bao gồm lọc, đặt hàng, v.v.
  • Hoạt động trên các bộ điều khiển - pagination-controlschỉ thị không cần biết gì về bối cảnh mà lệnh paginateđược gọi.

Bản trình diễn: http://plnkr.co/edit/Wtkv71LIqUR4OhzhgpqL?p=preview

Đối với những người đang tìm kiếm một giải pháp "cắm và chơi", tôi nghĩ bạn sẽ thấy điều này hữu ích.

Mã này có sẵn ở đây trên GitHub và bao gồm một bộ thử nghiệm khá tốt:

https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination

Nếu bạn quan tâm, tôi cũng đã viết một đoạn ngắn với cái nhìn sâu sắc hơn một chút về thiết kế của mô-đun: http://www.michaelbromley.co.uk/blog/108/paginate-al ultra-anything-in- angularjs /


Xin chào @michael bromley, tôi đang thử với angularUtils. Tôi đã thêm các tệp dirPangination.js và dirPagination.tpl.html vào dự án của mình. Nhưng tôi bắt đầu gặp lỗi như "[$ compile: tpload] Không thể tải mẫu: directives / pagination / dirPagination.tpl.html". Tôi đã cố gắng đặt tệp html này vào thư mục chỉ thị của dự án. Nhưng tôi đã không thành công. Tôi có những nghi ngờ sau: 1. Nơi để đặt dirPagination.tpl.html trong dự án (Khi tôi đang sử dụng ruby ​​trên đường ray với Angularjs)?
Vieenay Siingh

2
Không, bạn đã nhận được tôi tại thời điểm tôi đọc rằng phân trang có thể ở bất cứ đâu trong trang :) Hiện đang sử dụng nó và hoạt động trơn tru.
diosney

4
Đây là chỉ thị phân trang tốt nhất hiện có cho góc. Đây có lẽ là giải pháp đơn giản nhất để phân trang mà tôi từng thấy. Tôi đã lên và phân trang nhiều bảng cho mỗi lượt xem với mỗi bảng điều khiển phân trang riêng biệt trong 15 phút. Tất cả với hai dòng mã cho mỗi tệp .jade. Tất cả những gì tôi có thể nói là WOW. Tuyệt vời!
jrista

6
Tôi có thể bảo đảm cho sự tuyệt vời của chỉ thị này, tôi đã lặp lại ng phức tạp và nó đã xử lý nó không có vấn đề gì. Thiết lập siêu dễ dàng.
gkiely

1
Phương thức "tracker ()" của bạn tiết kiệm ngày của tôi. Tôi đã có một hành vi khủng khiếp và hiếm có mà không có nó.
Leopoldo Sanchot

63

Tôi vừa tạo một JSFiddle hiển thị phân trang + tìm kiếm + đặt hàng trên mỗi cột bằng mã btford: http://jsfiddle.net/SAWsA/11/


4
Cảm ơn các fiddle. Nó rất hữu ích. Câu hỏi mặc dù: làm thế nào bạn sẽ thực hiện sắp xếp trên toàn bộ tập kết quả thay vì những gì trên trang hiện tại?
super9

5
Lưu ý rằng việc sắp xếp chỉ hoạt động trên trang hiện tại ... Nó không sắp xếp toàn bộ mảng. Việc phân trang phải được làm lại mỗi khi bạn thay đổi thứ tự sắp xếp
dgn

3
@Spir: Có, tìm kiếm hoạt động, nhưng không sắp xếp. Nếu bạn đảo ngược sắp xếp trên trang 1, chỉ trang này được sắp xếp lại, thay vì hiển thị các mục 9, 20 và đồng
dgn

1
@AleckLandgraf tôi đã thử thêm $ scope.search nhưng ii vẫn không hiển thị danh sách được sắp xếp chính xác. xin vui lòng cho tôi biết những gì bạn đã cố gắng hoặc thêm vào
anam

1
@simmisimmi @Spir @scenario có một lỗi ở cuối javascript: new_sorting_ordernên có newSortingOrder. Khắc phục điều đó, thêm @scope.search();và bạn sẽ thấy mọi thứ sắp xếp như mong đợi và các biểu tượng sắp xếp cũng cập nhật. (Chạy fiddle với bảng điều khiển gỡ lỗi của trình duyệt của bạn mở (bằng chrome, F12, tab bảng điều khiển) và điều đó là hiển nhiên).
Dax Fohl

15

Tôi đã cập nhật plunkr của Scotty.NET http://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p=preview để nó sử dụng các phiên bản mới hơn của angular, angular-ui và bootstrap.

Bộ điều khiển

var todos = angular.module('todos', ['ui.bootstrap']);

todos.controller('TodoController', function($scope) {
  $scope.filteredTodos = [];
  $scope.itemsPerPage = 30;
  $scope.currentPage = 4;

  $scope.makeTodos = function() {
    $scope.todos = [];
    for (i=1;i<=1000;i++) {
      $scope.todos.push({ text:'todo '+i, done:false});
    }
  };

  $scope.figureOutTodosToDisplay = function() {
    var begin = (($scope.currentPage - 1) * $scope.itemsPerPage);
    var end = begin + $scope.itemsPerPage;
    $scope.filteredTodos = $scope.todos.slice(begin, end);
  };

  $scope.makeTodos(); 
  $scope.figureOutTodosToDisplay();

  $scope.pageChanged = function() {
    $scope.figureOutTodosToDisplay();
  };

});

Thành phần UI Bootstrap

 <pagination boundary-links="true" 
    max-size="3" 
    items-per-page="itemsPerPage"
    total-items="todos.length" 
    ng-model="currentPage" 
    ng-change="pageChanged()"></pagination>

giải pháp cập nhật này thực sự đáp ứng nhu cầu của tôi. Cảm ơn rất nhiều.
Suraj Lama

10

Đây là một giải pháp javascript thuần túy mà tôi đã gói gọn như một dịch vụ Angular để triển khai logic phân trang như trong kết quả tìm kiếm của google.

Bản demo hoạt động trên CodePen tại http://codepen.io/cornflourblue/pen/KVeaQL/

Chi tiết và giải thích tại bài viết trên blog này

function PagerService() {
    // service definition
    var service = {};

    service.GetPager = GetPager;

    return service;

    // service implementation
    function GetPager(totalItems, currentPage, pageSize) {
        // default to first page
        currentPage = currentPage || 1;

        // default page size is 10
        pageSize = pageSize || 10;

        // calculate total pages
        var totalPages = Math.ceil(totalItems / pageSize);

        var startPage, endPage;
        if (totalPages <= 10) {
            // less than 10 total pages so show all
            startPage = 1;
            endPage = totalPages;
        } else {
            // more than 10 total pages so calculate start and end pages
            if (currentPage <= 6) {
                startPage = 1;
                endPage = 10;
            } else if (currentPage + 4 >= totalPages) {
                startPage = totalPages - 9;
                endPage = totalPages;
            } else {
                startPage = currentPage - 5;
                endPage = currentPage + 4;
            }
        }

        // calculate start and end item indexes
        var startIndex = (currentPage - 1) * pageSize;
        var endIndex = startIndex + pageSize;

        // create an array of pages to ng-repeat in the pager control
        var pages = _.range(startPage, endPage + 1);

        // return object with all pager properties required by the view
        return {
            totalItems: totalItems,
            currentPage: currentPage,
            pageSize: pageSize,
            totalPages: totalPages,
            startPage: startPage,
            endPage: endPage,
            startIndex: startIndex,
            endIndex: endIndex,
            pages: pages
        };
    }
}

Tôi đã sử dụng cách tiếp cận của bạn nhưng vấn đề là nếu tôi muốn sử dụng index-es để đặt hàng trên trang, nó luôn được hiển thị là 0-9 ...
vaske

4

Tôi đã trích xuất các bit có liên quan ở đây. Đây là máy nhắn tin dạng bảng 'không rườm rà', do đó không bao gồm sắp xếp hoặc lọc. Hãy thoải mái thay đổi / thêm khi cần:

     //your data source may be different. the following line is 
     //just for demonstration purposes only
    var modelData = [{
      text: 'Test1'
    }, {
      text: 'Test2'
    }, {
      text: 'Test3'
    }];

    (function(util) {

      util.PAGE_SIZE = 10;

      util.range = function(start, end) {
        var rng = [];

        if (!end) {
          end = start;
          start = 0;
        }

        for (var i = start; i < end; i++)
          rng.push(i);

        return rng;
      };

      util.Pager = function(data) {
        var self = this,
          _size = util.PAGE_SIZE;;

        self.current = 0;

        self.content = function(index) {
          var start = index * self.size,
            end = (index * self.size + self.size) > data.length ? data.length : (index * self.size + self.size);

          return data.slice(start, end);
        };

        self.next = function() {
          if (!self.canPage('Next')) return;
          self.current++;
        };

        self.prev = function() {
          if (!self.canPage('Prev')) return;
          self.current--;
        };

        self.canPage = function(dir) {
          if (dir === 'Next') return self.current < self.count - 1;
          if (dir === 'Prev') return self.current > 0;
          return false;
        };

        self.list = function() {
          var start, end;
          start = self.current < 5 ? 0 : self.current - 5;
          end = self.count - self.current < 5 ? self.count : self.current + 5;
          return Util.range(start, end);
        };

        Object.defineProperty(self, 'size', {
          configurable: false,
          enumerable: false,
          get: function() {
            return _size;
          },
          set: function(val) {
            _size = val || _size;
          }
        });

        Object.defineProperty(self, 'count', {
          configurable: false,
          enumerable: false,
          get: function() {
            return Math.ceil(data.length / self.size);
          }
        });
      };

    })(window.Util = window.Util || {});

    (function(ns) {
      ns.SampleController = function($scope, $window) {
        $scope.ModelData = modelData;
        //instantiate pager with array (i.e. our model)
        $scope.pages = new $window.Util.Pager($scope.ModelData);
      };
    })(window.Controllers = window.Controllers || {});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-controller="Controllers.SampleController">
  <thead>
    <tr>
      <th>
        Col1
      </th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in pages.content(pages.current)" title="{{item.text}}">
      <td ng-bind-template="{{item.text}}"></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="4">
        <a href="#" ng-click="pages.prev()">&laquo;</a>
        <a href="#" ng-repeat="n in pages.list()" ng-click="pages.current = n" style="margin: 0 2px;">{{n + 1}}</a>
        <a href="#" ng-click="pages.next()">&raquo;</a>
      </td>
    </tr>
  </tfoot>
</table>


4

Giải pháp dưới đây khá đơn giản.

<pagination  
        total-items="totalItems" 
        items-per-page= "itemsPerPage"
        ng-model="currentPage" 
        class="pagination-sm">
</pagination>

<tr ng-repeat="country in countries.slice((currentPage -1) * itemsPerPage, currentPage * itemsPerPage) "> 

Đây là mẫu jsfiddle



3

Đối với bất cứ ai cảm thấy khó khăn như tôi để tạo ra một kẻ phân trang cho một bảng tôi đăng bài này. Vì vậy, theo quan điểm của bạn:

          <pagination total-items="total" items-per-page="itemPerPage"    ng-model="currentPage" ng-change="pageChanged()"></pagination>    
        <!-- To specify your choice of items Per Pages-->
     <div class="btn-group">
                <label class="btn btn-primary" ng-model="radioModel"  btn-radio="'Left'" data-ng-click="setItems(5)">5</label>
                <label class="btn btn-primary" ng-model="radioModel" btn-radio="'Middle'" data-ng-click="setItems(10)">10</label>
                <label class="btn btn-primary" ng-model="radioModel" btn-radio="'Right'" data-ng-click="setItems(15)">15</label>
            </div>
     //And don't forget in your table:
      <tr data-ng-repeat="p in profiles | offset: (currentPage-1)*itemPerPage | limitTo: itemPerPage" >

Trong góc của bạn:

  var module = angular.module('myapp',['ui.bootstrap','dialogs']);
  module.controller('myController',function($scope,$http){
   $scope.total = $scope.mylist.length;     
   $scope.currentPage = 1;
   $scope.itemPerPage = 2;
   $scope.start = 0;

   $scope.setItems = function(n){
         $scope.itemPerPage = n;
   };
   // In case you can replace ($scope.currentPage - 1) * $scope.itemPerPage in <tr> by "start"
   $scope.pageChanged = function() {
        $scope.start = ($scope.currentPage - 1) * $scope.itemPerPage;
            };  
});
   //and our filter
     module.filter('offset', function() {
              return function(input, start) {
                start = parseInt(start, 10);
                return input.slice(start);
              };
            });     

Có những câu trả lời với rất nhiều sự ủng hộ và tích cực .. nhưng không có câu trả lời nào cho tôi cả .. nhưng câu trả lời này kết hợp với câu trả lời của @svarog có tác dụng như một cơ duyên đối với tôi.
Rai


3

Kể từ Angular 1.4, limitTobộ lọc cũng chấp nhận đối số tùy chọn thứ haibegin

Từ các tài liệu :

{{limitTo_expression | giới hạn: giới hạn: bắt đầu}}

bắt đầu (tùy chọn) chuỗi | số
Chỉ mục để bắt đầu giới hạn. Là một chỉ số tiêu cực, bắt đầu chỉ ra một phần bù từ cuối đầu vào. Mặc định là 0.

Vì vậy, bạn không cần phải tạo một lệnh mới , Đối số này có thể được sử dụng để đặt phần bù của phân trang

ng-repeat="item in vm.items| limitTo: vm.itemsPerPage: (vm.currentPage-1)*vm.itemsPerPage" 

3

Bạn có thể dễ dàng thực hiện việc này bằng chỉ thị Bootstrap UI.

Câu trả lời này là một sửa đổi của câu trả lời được đưa ra bởi @ Scotty.NET, tôi đã thay đổi mã vì lệnh <pagination>này hiện không được chấp nhận.

Mã sau tạo phân trang:

<ul uib-pagination 
    boundary-links="true"  
    total-items="totalItems"  
    items-per-page="itemsPerPage"  
    ng-model="currentPage"  
    ng-change="pageChanged()"  
    class="pagination"  
    previous-text="&lsaquo;"  
    next-text="&rsaquo;"  
    first-text="&laquo;"  
    last-text="&raquo;">
</ul>

Để làm cho nó hoạt động, sử dụng điều này trong bộ điều khiển của bạn:

$scope.filteredData = []
$scope.totalItems = $scope.data.length;
$scope.currentPage = 1;
$scope.itemsPerPage = 5;

$scope.setPage = function (pageNo) {
    $scope.currentPage = pageNo;
};

$scope.pageChanged = function() {
    var begin = (($scope.currentPage - 1) * $scope.itemsPerPage)
    , end = begin + $scope.itemsPerPage;

    $scope.filteredData = $scope.data.slice(begin, end);
};

$scope.pageChanged();

Tham khảo điều này để biết thêm các tùy chọn phân trang: Chỉ thị phân trang UI Bootstrap


2

phân trang lặp lại

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

<script>

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

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

 $scope.getData = function () {

  return $filter('filter')($scope.data, $scope.q)

   }

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

   for (var i=0; i<65; i++) {
    $scope.data.push("Item "+i);
   }
  }]);

        app.filter('startFrom', function() {
    return function(input, start) {
    start = +start; //parse to int
    return input.slice(start);
   }
  });
  </script>

1

Các tin nhắn trước đây đề xuất về cơ bản làm thế nào để tự xây dựng một trang. Nếu bạn giống tôi và thích một chỉ thị hoàn thành, tôi chỉ tìm thấy một thứ tuyệt vời gọi là ngTable . Nó hỗ trợ sắp xếp, lọc và phân trang.

Đó là một giải pháp rất sạch sẽ, tất cả những gì bạn cần trong quan điểm của mình:

   <table ng-table="tableParams" class="table">
        <tr ng-repeat="user in $data">
            <td data-title="'Name'" sortable="'name'">
                {{user.name}}
            </td>
            <td data-title="'Age'" sortable="'age'">
                {{user.age}}
            </td>
        </tr>
    </table>

Và trong bộ điều khiển:

$scope.tableParams = new ngTableParams({
    page: 1,            // show first page
    count: 10,          // count per page
    sorting: {
        name: 'asc'     // initial sorting
    }
}, {
    total: data.length, // length of data
    getData: function($defer, params) {
        // use build-in angular filter
        var orderedData = params.sorting() ?
                            $filter('orderBy')(data, params.orderBy()) :
                            data;

        var start = (params.page() - 1) * params.count();
        var end = params.page() * params.count();

        $defer.resolve(orderedData.slice( start, end));
    }
});

Liên kết với GitHub: https://github.com/esvit/ng-table/


1

Phân trang góc

là một lựa chọn tuyệt vời

Một chỉ thị để hỗ trợ phân trang bộ dữ liệu lớn trong khi yêu cầu tối thiểu thông tin phân trang thực tế. Chúng tôi rất phụ thuộc vào máy chủ để "lọc" kết quả trong sơ đồ phân trang này. Ý tưởng trung tâm là chúng tôi chỉ muốn giữ "trang" hoạt động của các mục - thay vì giữ toàn bộ danh sách các mục trong bộ nhớ và phân trang ở phía máy khách.


1

Câu hỏi cũ nhưng vì tôi nghĩ cách tiếp cận của tôi hơi khác một chút và ít phức tạp hơn nên tôi sẽ chia sẻ điều này và hy vọng rằng ai đó bên cạnh tôi thấy nó hữu ích.

Những gì tôi thấy là một giải pháp dễ dàng và nhỏ để phân trang là kết hợp một lệnh với một bộ lọc sử dụng các biến phạm vi tương tự.

Để thực hiện điều này, bạn thêm bộ lọc vào mảng và thêm directiv như thế này

<div class="row">
    <table class="table table-hover">
        <thead>
            <tr>
                <th>Name</th>
                <th>Price</th>
                <th>Quantity</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="item in items | cust_pagination:p_Size:p_Step">
                <td>{{item.Name}}</td>
                <td>{{item.Price}}</td>
                <td>{{item.Quantity}}</td>
            </tr>
        </tbody>
    </table>
    <div cust-pagination p-items="items" p-boundarylinks="true" p-size="p_Size" p-step="p_Step"></div>
</div>

p_Size và p_Step là các biến phạm vi có thể được tùy chỉnh trong phạm vi khác giá trị mặc định của p_Size là 5 và p_Step là 1.

Khi một bước thay đổi trong phân trang, p_Step được cập nhật và sẽ kích hoạt một bộ lọc mới bằng bộ lọc obl_pagination. Sau đó, bộ lọc obl_pagination sẽ cắt mảng tùy thuộc vào giá trị p_Step như bên dưới và chỉ trả về các bản ghi hoạt động được chọn trong phần phân trang

var startIndex = nStep * nPageSize;
var endIndex = startIndex + nPageSize;
var arr = items.slice(startIndex, endIndex);
return arr;

DEMO Xem giải pháp hoàn chỉnh trong plunker này


0

Có ví dụ của tôi. Nút được chọn ở giữa trong danh sách Bộ điều khiển. cấu hình >>>

 $scope.pagination = {total: null, pages: [], config: {count: 10, page: 1, size: 7}};

Logic cho phân trang:

/*
     Pagination
     */
    $scope.$watch('pagination.total', function (total) {
        if(!total || total <= $scope.pagination.config.count) return;
        _setPaginationPages(total);
    });

    function _setPaginationPages(total) {
        var totalPages = Math.ceil(total / $scope.pagination.config.count);
        var pages = [];
        var start = $scope.pagination.config.page - Math.floor($scope.pagination.config.size/2);
        var finish = null;

        if((start + $scope.pagination.config.size - 1) > totalPages){
            start = totalPages - $scope.pagination.config.size;
        }
        if(start <= 0) {
            start = 1;
        }

       finish = start +  $scope.pagination.config.size - 1;
       if(finish > totalPages){
           finish = totalPages;
       }


        for (var i = start; i <= finish; i++) {
            pages.push(i);
        }

        $scope.pagination.pages = pages;
    }

    $scope.$watch("pagination.config.page", function(page){
        _setPaginationPages($scope.pagination.total);
        _getRespondents($scope.pagination.config);
    });

và quan điểm của tôi về bootstap

<ul ng-class="{hidden: pagination.total == 0}" class="pagination">
        <li ng-click="pagination.config.page = pagination.config.page - 1"
            ng-class="{disabled: pagination.config.page == 1}" ><a href="#">&laquo;</a></li>
        <li ng-repeat="p in pagination.pages"
            ng-click="pagination.config.page = p"
            ng-class="{active: p == pagination.config.page}"><a href="#">{{p}}</a></li>
        <li ng-click="pagination.config.page = pagination.config.page + 1"
            ng-class="{disabled: pagination.config.page == pagination.pages.length}"><a href="#">&raquo;</a></li>
    </ul >

Nó rất hữu ích


0

Tôi ước tôi có thể bình luận, nhưng tôi sẽ phải để nó ở đây:

Câu trả lời của Scotty.NET và bản làm lại của người dùng2176745 cho các phiên bản sau đều tuyệt vời, nhưng cả hai đều bỏ lỡ điều gì đó mà phiên bản AngularJS (v1.3.15) của tôi bị hỏng:

tôi không được định nghĩa trong $ scope.makeTodos.

Như vậy, thay thế bằng chức năng này sẽ sửa nó cho các phiên bản góc cạnh gần đây hơn.

$scope.makeTodos = function() {
    var i;
    $scope.todos = [];
    for (i=1;i<=1000;i++) {
        $scope.todos.push({ text:'todo '+i, done:false});
    }
};

0

Tổng quan : Phân trang bằng

 - ng-repeat
 - uib-pagination

Xem :

<div class="row">
    <div class="col-lg-12">
        <table class="table">
            <thead style="background-color: #eee">
                <tr>
                    <td>Dispature</td>
                    <td>Service</td>
                    <td>Host</td>
                    <td>Value</td>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="x in app.metricsList">
                    <td>{{x.dispature}}</td>
                    <td>{{x.service}}</td>
                    <td>{{x.host}}</td>
                    <td>{{x.value}}</td>
                </tr>
            </tbody>
        </table>

        <div align="center">
            <uib-pagination items-per-page="app.itemPerPage" num-pages="numPages"
                total-items="app.totalItems" boundary-link-numbers="true"
                ng-model="app.currentPage" rotate="false" max-size="app.maxSize"
                class="pagination-sm" boundary-links="true"
                ng-click="app.getPagableRecords()"></uib-pagination>        

            <div style="float: right; margin: 15px">
                <pre>Page: {{app.currentPage}} / {{numPages}}</pre>
            </div>          
        </div>
    </div>
</div>

Trình điều khiển JS :

app.controller('AllEntryCtrl',['$scope','$http','$timeout','$rootScope', function($scope,$http,$timeout,$rootScope){

    var app = this;
    app.currentPage = 1;
    app.maxSize = 5;
    app.itemPerPage = 5;
    app.totalItems = 0;

    app.countRecords = function() {
        $http.get("countRecord")
        .success(function(data,status,headers,config){
            app.totalItems = data;
        })
        .error(function(data,status,header,config){
            console.log(data);
        });
    };

    app.getPagableRecords = function() {
        var param = {
                page : app.currentPage,
                size : app.itemPerPage  
        };
        $http.get("allRecordPagination",{params : param})
        .success(function(data,status,headers,config){
            app.metricsList = data.content;
        })
        .error(function(data,status,header,config){
            console.log(data);
        });
    };

    app.countRecords();
    app.getPagableRecords();

}]);

0

Tôi muốn thêm giải pháp của tôi hoạt động với ngRepeatvà các bộ lọc mà bạn sử dụng với nó mà không cần sử dụng một $watchhoặc một mảng cắt lát.

Kết quả lọc của bạn sẽ được phân trang!

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

app.controller('myController', ['$scope', function($scope){
    $scope.list= ['a', 'b', 'c', 'd', 'e'];

    $scope.pagination = {
        currentPage: 1,
        numPerPage: 5,
        totalItems: 0
    };

    $scope.searchFilter = function(item) {
        //Your filter results will be paginated!
        //The pagination will work even with other filters involved
        //The total number of items in the result of your filter is accounted for
    };

    $scope.paginationFilter = function(item, index) {
        //Every time the filter is used it restarts the totalItems
        if(index === 0) 
            $scope.pagination.totalItems = 0;

        //This holds the totalItems after the filters are applied
        $scope.pagination.totalItems++;

        if(
            index >= (($scope.pagination.currentPage - 1) * $scope.pagination.numPerPage)
            && index < ((($scope.pagination.currentPage - 1) * $scope.pagination.numPerPage) + $scope.pagination.numPerPage)
        )
            return true; //return true if item index is on the currentPage

        return false;
    };
}]);

Trong HTML, đảm bảo rằng bạn áp dụng các bộ lọc của mình cho ngRepeat trước bộ lọc phân trang.

<table data-ng-controller="myController">
    <tr data-ng-repeat="item in list | filter: searchFilter | filter: paginationFilter track by $index">
        <td>
            {{item}}
        </td>
    <tr>
</table>
<ul class="pagination-sm"
    uib-pagination
    data-boundary-links="true"
    data-total-items="pagination.totalItems"
    data-items-per-page="pagination.numPerPage"
    data-ng-model="pagination.currentPage"
    data-previous-text="&lsaquo;"
    data-next-text="&rsaquo;"
    data-first-text="&laquo;"
    data-last-text="&raquo;">
 </ul>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.