Як зробити пейджинговий виклик в AngularJS?


254

У мене є набір даних про близько 1000 елементів в пам'яті і я намагаюся створити пейджер для цього набору даних, але я не впевнений, як це зробити.

Я використовую спеціальну функцію фільтра для фільтрації результатів, і це працює чудово, але мені потрібно якось отримати кількість сторінок.

Будь-які підказки?


Відповіді:


285

Угловий завантажувальний інтерфейс UI - Директива про створення сторінок

Ознайомтеся з директивою щодо розширення інтерфейсу Bootstrap щодо створення сторінки . Я в кінцевому рахунку використовував його, а не те, що розміщено тут, оскільки він має достатньо функцій для мого поточного використання та має ретельну тестову характеристику яка супроводжує його.

Вид

<!-- table here -->

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

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

Контролер

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

Я зробив робочий плункер для довідки.


Спадкова версія:

Вид

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

Контролер

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

Я зробив робочий плункер для довідки.


2
приємно і елегантно. Це можна було б покращити, додавши сорт
Карлос Барселона

3
Атрибут num-pages більше не потрібен і лише для читання. Не потрібно передавати numPages. Дивіться документи: angular-ui.github.io/bootstrap/#/pagination
kvetis

3
РЕШЕНО: items-per-page - це властивість, яку потрібно встановити в paginationелементі.
Богач

1
^^^^ Для всіх нових читачів дивіться коментар Bogacs: пункти на сторінку тепер потрібні в елементі сторінки. Без нього не працює.
IfTrue

14
<pagination> тепер застаріло. Використовуйте замість <uib-pagination>.
mnm

88

Нещодавно я здійснив пейджінг для сайту "Вбудований з кутовим". Ви можете перевірити джерело: https://github.com/angular/builtwith.angularjs.org

Я б не використовував фільтр для розділення сторінок. Ви повинні розділити елементи на сторінки в контролері.


61
Рішення поширюється на кілька файлів. Потрібно заглянути хоча б у контролер і вигляд. Я не бачу, як це вимагає перемоги: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
Ви можете почати переглядати <div class = "pagination"> index.html github.com/angular/builtwith.angularjs.org/blob/master/…
Хорхе Нунес Ньютон

6
@btford Чому б ти не використовував фільтр?
CWSпочаток

4
Я вирішив протидіяти попередньому голосуванню, оскільки я вважав, що плакат є якісним прикладом, який можна використовувати для відповіді на початкове запитання.
RachelD

1
@btford Чи все-таки погана ідея боліти за допомогою фільтра? Ось плункр, що створює список сторінок за допомогою фільтра, який здається виконавцем (принаймні, у цьому тривіальному прикладі до 10 000 000 рядків): embed.plnkr.co/iWxWlCEvd6Uh8erUOyaF
Ryan Kimber,

79

Мені довелося впроваджувати пагинацію досить багато разів за допомогою Angular, і це завжди було болю за те, що я вважав, що можна спростити. Я використовував деякі ідеї, представлені тут і в інших місцях, щоб зробити модуль сторінки, який робить сторінки просто так просто:

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

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

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

Це воно. Він має такі особливості:

  • Не потрібний спеціальний код у контролері, щоб зв’язати колекцію items до посилань на сторінки.
  • Ви не зобов’язані використовувати таблицю або gridview - ви можете додати до сторінки все, що ви можете ng-повторити!
  • Делегується до ng-repeat, тому ви можете використовувати будь-який вираз, який міг би бути коректно використаний у ng-repeat, включаючи фільтрування, замовлення тощо.
  • Працює через контролери - pagination-controlsдирективі не потрібно нічого знати про контекст, в якому paginateназивається директива.

Демонстраційний: http://plnkr.co/edit/Wtkv71LIqUR4OhzhgpqL?p=preview

Для тих, хто шукає рішення «підключись і грай», я думаю, це стане корисним.

Код

Код доступний тут на GitHub і включає досить хороший набір тестів:

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

Якщо вас цікавить, я також написав короткий твір з трохи більше розуміння дизайну модуля: http://www.michaelbromley.co.uk/blog/108/paginate-almost-anything-in-angularjs/


Привіт @michael bromley, я намагаюся з angularUtils. Я додав файли dirPangination.js та dirPagination.tpl.html до свого проекту. Але я почав отримувати помилки на кшталт "[$ compile: tpload] Не вдалося завантажити шаблон: директиви / сторінки / dirPagination.tpl.html". Я намагався помістити цей HTML-файл у папку директив мого проекту. Але я не мав успіху. У мене є такі сумніви: 1. Де розмістити dirPagination.tpl.html у проекті (Оскільки я використовую рубін на рейках з Angularjs)?
Vieenay Siingh

2
Акуратний, ти здобув мене в той момент, коли я прочитав, що пагинація може бути в будь-якій точці сторінки.
діосней

4
Це найкраща директива щодо підключення сторінок для кутових. Це, мабуть, найпростіше рішення для пейджингу, яке я коли-небудь бачив. Я розробляв і підкачував декілька таблиць на перегляд у кожній із власним ізольованим контролем підкачки за 15 хвилин. Все з двома рядками коду на .jade файл. Все, що я можу сказати, - WOW. Дивовижно!
jrista

6
Я можу поручитися за дивовижність цієї директиви, у мене було складне ng-повторення, і це вирішило це без проблем. Супер просте налаштування.
gkiely

1
Ваш метод "tracker ()" врятує мій день. Я мав жахливу і рідкісну поведінку без цього.
Леопольдо Санчик

63

Щойно я створив JSFiddle, який показує пагинацію + пошук + порядок у кожному стовпчику, використовуючи код btford: http://jsfiddle.net/SAWsA/11/


4
Дякую за загадку. Це дуже корисно. Питання, однак: як би ви реалізували сортування над усім набором результатів замість того, що є на поточній сторінці?
super9

5
Зауважте, що сортування працює лише на поточній сторінці ... Це не сортує весь масив. Пагинацію потрібно переробляти щоразу, коли ви змінюєте порядок сортування
грудня 1313

3
@Spir: Так, пошук робіт, але не сортування. Якщо ви реверс сортування на сторінці 1, тільки ця сторінка замовлена, замість відображення пунктів 9, 20 і Ко
DGN

1
@AleckLandgraf я спробував додати $ range.search, але ii все ще не відображає правильний відсортований список. будь ласка, дайте мені знати, що ще ви спробували чи додали
анам

1
@simmisimmi @Spir @scenario внизу javascript є помилка: new_sorting_orderмає бути newSortingOrder. Виправте це, додайте @scope.search();, і ви побачите речі сортувати так, як очікувалося, і піктограми сортування також оновлять. (Запустіть скрипку з відкритою консоллю налагодження веб-переглядача (в хромі, F12, вкладці консолі), і це очевидно).
Дакс Фол

15

Я оновив plunkr Scotty.NET http://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p=preview який використовує новіші версії -ui та bootstrap.

Контролер

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

});

Компонент інтерфейсу завантажувача

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

це оновлене рішення дійсно відповідало моїм потребам. Дуже дякую.
Сурай-лама

10

Це чисте javascript-рішення, яке я розгорнув як службу Angular для впровадження логіки сторінки, як у результатах пошуку Google.

Робоча демонстрація програми CodePen за адресою http://codepen.io/cornflourblue/pen/KVeaQL/

Деталі та пояснення у цій публікації в блозі

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

Я використовував ваш підхід, але проблема полягає в тому, що якщо я хочу використовувати індекси для замовлення на сторінці, це завжди відображається як 0-9 ...
vaske

4

Тут я витягнув відповідні шматочки. Це табличний пейджер "без надмірностей", тому сортування чи фільтрування не включаються. Ви можете змінити / додати за потреби:

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

Нижче рішення досить просте.

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

Ось зразок jsfiddle


3

Кутовий адаптер jQuery Mobile має фільтр підкачки, на якому можна базуватися.

Ось демонстраційна скрипка, яка використовує її (додайте більше 5 елементів, і вона стає підказкою): http://jsfiddle.net/tigbro/Du2DY/

Ось джерело: https://github.com/tigbro/jquery-mobile-angular-adapter/blob/master/src/main/webapp/utils/paging.js


3

Для тих, кому важко, як я, створити пагінатор таблиці, яку я розміщую. Отже, на ваш погляд:

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

У ваших кутових J:

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

Було відповіді з такою кількістю відгуків і позитивів .. але жоден не працював на мене .. але цей у поєднанні з відповіддю @svarog спрацював як шарм для мене.
Рай

3

Я використовую цю третю сторону бібліотеки сторінки, і вона добре працює. Він може робити локальні / віддалені джерела даних, і це дуже настроюється.

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

<dir-pagination-controls
    [max-size=""]
    [direction-links=""]
    [boundary-links=""]
    [on-page-change=""]
    [pagination-id=""]
    [template-url=""]
    [auto-hide=""]>
    </dir-pagination-controls>

3

Оскільки Angular 1.4, limitToфільтр також приймає другий необов'язковий аргументbegin

З документів :

{{limitTo_expression | limitTo: limit: почати}}

start (необов'язково) рядок | число
Індекс, на якому слід розпочати обмеження. Як від'ємний індекс, start позначає зміщення від кінця введення. За замовчуванням до 0.

Тому вам не потрібно створювати нову директиву. Цей аргумент може бути використаний для встановлення зміщення сторінки

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

3

Ви можете легко зробити це за допомогою директиви Bootstrap UI.

Ця відповідь є модифікацією відповіді, наданої @ Scotty.NET, я змінив код, оскільки <pagination>директива застаріла.

Наступний код генерує пагінацію:

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

Щоб зробити його функціональним, використовуйте це у своєму контролері:

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

Для цього див. Додаткові параметри розбиття сторінки: Директива про завантаження користувальницького інтерфейсу Bootstrap


2

ng-повторення сторінки

    <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

Попередні повідомлення в основному рекомендували, як створити підкачку самостійно. Якщо ви схожі на мене і віддаєте перевагу готовій директиві, я просто знайшов чудовий під назвою ngTable . Він підтримує сортування, фільтрацію та пагинацію.

Це дуже чисте рішення, все що вам потрібно:

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

І в контролері:

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

Посилання на GitHub: https://github.com/esvit/ng-table/


1

Кутово-Пейджинг

чудовий вибір

Директива, яка допомагає створювати підкачки великих наборів даних, вимагаючи мінімум фактичної інформації про підключення. Ми дуже залежні від сервера для "фільтрації" результатів у цій схемі підкачки. Основна ідея полягає в тому, що ми хочемо лише тримати активну "сторінку" елементів, а не зберігати весь список елементів у пам'яті та підкачки на стороні клієнта.


1

Старе питання, але оскільки я думаю, що мій підхід дещо інший і менш складний, я поділюсь цим і сподіваюся, що хтось, окрім мене, вважає його корисним.

Те, що я вважав простим і малим рішенням сторінки, полягає в поєднанні директиви з фільтром, який використовує ті самі змінні області.

Щоб реалізувати це, ви додаєте фільтр до масиву і додаєте такий directiv, як цей

<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 і p_Step - це змінні області, які можна налаштувати у межах іншого значення, за замовчуванням значення p_Size становить 5, а p_Step - 1.

Коли крок зміни сторінки, оновлення p_Step оновлюється і запускає нове фільтрування за допомогою фільтра cust_pagination. Потім Filter_pagination Filter відрізає масив залежно від значення p_Step, як показано нижче, і повертає лише активні записи, вибрані в розділі сторінки

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

DEMO Переглянути повне рішення в цьому планку


0

Є мій приклад. Вибрана кнопка посередині в списку Контролер. конфігурація >>>

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

Логіка пагинації:

/*
     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);
    });

і мій погляд на завантажувальну систему

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

Це корисно


0

Я б хотів, щоб я міг прокоментувати, але мені просто доведеться залишити це тут:

Відповідь Scotty.NET та повтор користувача2176745 для пізніших версій - це чудово, але вони обоє пропускають щось, на що зламається моя версія AngularJS (v1.3.15):

i не визначено в $ range.makeTodos.

Таким чином, заміна цієї функції виправляє її для новіших кутових версій.

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

0

Огляд : Використання сторінки з використанням сторінки

 - ng-repeat
 - uib-pagination

Вид :

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

Контролер 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

Я хотів би додати своє рішення, яке працює з, ngRepeatі фільтри, які ви використовуєте з ним, не використовуючи $watchмасив або нарізаний масив.

Ваші результати фільтру будуть болісними!

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

У HTML переконайтесь, що ви застосували ваші фільтри до фільтра ngRepeat перед пагінацією.

<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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.