Angulr에서의 List 출력과 Pagination

PagerService 준비하기

출력하고자 하는 데이터를 페이지에 담기 위한 PagerService를 준비한다.

PagerService

import * as _ from 'underscore';

export class PagerService {
    getPager(totalItems: number, currentPage: number = 1, pageSize: number = 10) {
        // calculate total pages
        let totalPages = Math.ceil(totalItems / pageSize);

        let startPage: number, endPage: number;
        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
        let startIndex = (currentPage - 1) * pageSize;
        let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

        // create an array of pages to ng-repeat in the pager control
        let 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
        };
    }
}

component.ts 혹은 데이터를 총괄하는 service.ts

컴포넌트에서 사용할 두 변수를 선언한다

  // pager object
  pager: any = {};
  // paged items
  pagedItems: any[];

컴포넌트에서 pagerService를 import하고 특정 페이지로 이동하기 위한 함수인 setPage()함수를 정의한다.

  setPage(page: number) {
      if (page < 1 || page > this.pager.totalPages) {
          return;
      }
      // get pager object from service
      this.pager = this.pagerService.getPager(this.contents.length, page,6);

      // get current page of items
      this.pagedItems = this.contents.slice(this.pager.startIndex, this.pager.endIndex + 1);
  }

pagedItems에는 받아온 데이터를 pager의 startIndex와 endIndex+1까지로 잘라 담아준다.

component.html

실제 pagination을 입혀준다.

  <div class="row-wrapper">
    <nav class="" style="display:inline-block">
      <!-- pager -->
      <ul *ngIf="paymentService.pager.pages && paymentService.pager.pages.length" class="pagination">
        <li [ngClass]="{disabled:paymentService.pager.currentPage === 1}" class="page-item">
            <a class="page-link direction first" (click)="paymentService.setPage(1)" aria-label="First">First</a>
        </li>
        <li [ngClass]="{disabled:paymentService.pager.currentPage === 1}" class="page-item">
            <a class="page-link direction previous" (click)="paymentService.setPage(paymentService.pager.currentPage - 1)" aria-label="Previous">Prev</a>
        </li>
        <li *ngFor="let page of paymentService.pager.pages" [ngClass]="{active:paymentService.pager.currentPage === page}" class="page-item">
        {% raw %}
            <a class="page-link" (click)="paymentService.setPage(page)">{{page}}</a>
            {% endraw %}
        </li>
        <li [ngClass]="{disabled:paymentService.pager.currentPage === paymentService.pager.totalPages}" class="page-item">
            <a class="page-link direction next" (click)="paymentService.setPage(paymentService.pager.currentPage + 1)" aria-label="Next">Next</a>
        </li>
        <li [ngClass]="{disabled:paymentService.pager.currentPage === paymentService.pager.totalPages}" class="page-item">
            <a class="page-link direction last" (click)="paymentService.setPage(paymentService.pager.totalPages)" aria-label="Last">Last</a>
        </li>
      </ul>
    </nav>
  </div>

다음을 클릭할때에는 service.ts의 setPage()를 호출하여 pagedItems를 바꾸어 준다. 만약에 데이터를 index를 통해 나누어 받아오고 싶은 경우에는 setPage()의 if 문에서 범위를 넘는 페이지의 요청에 대해 서버에 요청을 날려 다음 데이터들을 받아올 수 있다.