Открыть меню    

Создаем компонент пагинации в angular 4

Создаем компонент пагинации в angular 4

Довольноп просто создать свой собственный компонент в angular 4 (подозреваю все будет прекрасно работать и в 5 angular).

1. Создаем основу компонента

Начнем создание компонента с простых вещей:

// pagination.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-pagination',
  templateUrl: './pagination.component.html',
  styleUrls: ['./pagination.component.css']
})
export class PaginationComponent {

  constructor() {}

}
<!-- pagination.component.html -->
<div class="pagination">

</div>
/* pagination.component.scss */
.pagination {
}

2. Определим входные и выходные свойства компонента

  • Во-первых, нам нужно знать общее число элементов (items).
  • Затем нам потребуется знать на какой странице мы находимся.
  • Затем нам нужно знать сколько элементов отображается на странице.
  • Далее нужно узнать как много страниц расположить между кнопками 'предыдущая' и 'далее'.
  • Наконец, нам потребуется сделать некоторые действия, чтобы disable пагинацию на время загрузки контента.

Вот как это выглядит:

// pagination.component.ts
import { Component, Input } from '@angular/core';

...

export class PaginationComponent {
  @Input() page: number;    // the current page
  @Input() count: number;   // how many total items there are in all pages
  @Input() perPage: number; // how many items we want to show per page
  @Input() pagesToShow: number; // how many pages between next/prev
  @Input() loading: boolean;    // check if content is being loaded

  constructor() {}

  ...

}

Также потребуется некоторый callback, который будет выполнен, когда пользователь кликнет по кнопкам 'предыдущая'/'далее' или по номеру страницы. DOM-элементы будут созданы чуть позднее

// pagination.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';

...

export class PaginationComponent {

  // @Input() xyz
  ...

  @Output() goPrev = new EventEmitter<boolean>();
  @Output() goNext = new EventEmitter<boolean>();
  @Output() goPage = new EventEmitter<number>();

  constructor() {}

  ...

}
<!-- list.component.html -->
<pagination
  [count]="someCountVar"
  [page]="somePageVar"
  [perPage]="somePerPageVar"
  [pagesToShow]="5"
  [loading]="someLoadingVar"
  (onPrev)="prevPage()"
  (onNext)="nextPage()"
  (onPage)="goToPage($event)">
</pagination>

3. Заполним HTML шаблон компонента пагинации

Сейчас давайте создадим заполнители для всех элементов пагинации. Я получил что-то наподобие:

Здесь будут использоваться несколько методов, которые я создаду на следующем шаге. Не лучший способ использовать во view методы, но в нашем случае это некритично.

<!-- pagination.component.html -->
<div class="pagination" *ngIf="count > 0">
  <span>{{ getMin() }} of {{ getMax() }} of {{ count }}</span>
  <span>{{ totalPages() }} pages</span>
  <button (click)="onPrev()" [disabled]="page === 1 || loading">Previous</button>
  <button *ngFor="let pageNum of getPages()" (click)="onPage(pageNum)"></button>
  <button (click)="onNext()" [disabled]="lastPage() || loading">Next</button>
</div>

Пришло время для матемитики, другими словами время рассчитать все эти вещи. Я скопировал весь свой код из файла pagination.component.ts, чтобы вы могли увидеть все вместе.

// pagination.component.ts
import { Component, Input, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'my-pagination',
  templateUrl: './pagination.component.html',
  styleUrls: ['./pagination.component.scss']
})
export class PaginationComponent {
  @Input() page: number;
  @Input() count: number;
  @Input() perPage: number;
  @Input() loading: boolean;
  @Input() pagesToShow: number;

  @Output() goPrev = new EventEmitter<boolean>();
  @Output() goNext = new EventEmitter<boolean>();
  @Output() goPage = new EventEmitter<number>();

  constructor() { }

  getMin(): number {
    return ((this.perPage * this.page) - this.perPage) + 1;
  }

  getMax(): number {
    let max = this.perPage * this.page;
    if (max > this.count) {
      max = this.count;
    }
    return max;
  }

  onPage(n: number): void {
    this.goPage.emit(n);
  }

  onPrev(): void {
    this.goPrev.emit(true);
  }

  onNext(next: boolean): void {
    this.goNext.emit(next);
  }

  totalPages(): number {
    return Math.ceil(this.count / this.perPage) || 0;
  }

  lastPage(): boolean {
    return this.perPage * this.page > this.count;
  }

  getPages(): number[] {
    const c = Math.ceil(this.count / this.perPage);
    const p = this.page || 1;
    const pagesToShow = this.pagesToShow || 9;
    const pages: number[] = [];
    pages.push(p);
    const times = pagesToShow - 1;
    for (let i = 0; i < times; i++) {
      if (pages.length < pagesToShow) {
        if (Math.min.apply(null, pages) > 1) {
          pages.push(Math.min.apply(null, pages) - 1);
        }
      }
      if (pages.length < pagesToShow) {
        if (Math.max.apply(null, pages) < c) {
          pages.push(Math.max.apply(null, pages) + 1);
        }
      }
    }
    pages.sort((a, b) => a - b);
    return pages;
  }
}

Наконец это все, что вам требуется для рабочей пагинации. Отметим несколько вещей: вам нужно передать компоненту несколько переменных (например, текущая страница, общее число элементов/items, страниц для отображения и т.д.). Информацию о следующей странице вы получается постредством сервиса.

Источник: create-a-pagination-component-in-angular-4


7834
direct 7834
direct 7834


7605
direct 7605
direct 7605/


112

Комментарии к статье