Как настроить мат-пагинатор из угловатого материала

Я хочу настроить mat-paginator. По умолчанию я получаю paginator, подобный этому, который указан в ссылке ниже https://material.angular.io/components/paginator/overview. Но мне нужна разбивка на страницы, как на изображении ниже. Как это сделать с помощью мат-пагинатор

Как настроить мат-пагинатор из угловатого материала

Может ли кто-нибудь помочь мне с этим.

Лучшие 10 тем на основе Angular Material
Лучшие 10 тем на основе Angular Material
Затрудняетесь выбрать подходящие шаблоны и темы для своего проекта? Потерялись в огромном количестве вариантов? Не волнуйтесь, мы решили эту проблему...
17
0
30 225
6

Ответы 6

ОБНОВИТЬ 20.08.2020


Используя ответ @uhamid в качестве вдохновения, а также несколько комментариев ниже, указывающих, что это действительно возможно, я пересмотрел свою первую попытку предоставить полное решение.

Хотя приведенный ниже пример Umair Hamid является функциональным, он не включает требуемый стиль. Он также использовал ngDoCheck, который вводит поведение рекурсивного типа и, вероятно, приведет к проблемам с производительностью.

Я также переработал большую часть логики, чтобы получить более полное решение.

Используйте это как:

<mat-paginator style-paginator showFirstLastButtons [showTotalPages] = "3" [length] = "7130" [pageSize] = "10" [pageSizeOptions] = "[5, 10, 25, 100]"> </mat-paginator>

Предоставьте кнопки страниц для отображения в качестве входных данных [showTotalPages], если они не указаны, по умолчанию будет использоваться 2.



STACKBLITZ

https://stackblitz.com/edit/angular-wyx2ue-bw95ug?embed=1&file=app/style-paginator.directive.ts

ПЕРЕСМОТР STACKBLITZ 20.08.2020

https://stackblitz.com/edit/angular-8holwx?file=src/app/style-paginator.directive.ts

Хорошо. Спасибо за помощь @Marshal

ananya 11.12.2018 06:17

Спасибо за это решение. Я пробовал, но когда я нажимаю на номер страницы, страница не меняется. Кроме того, если я нажму кнопку «Далее и предыдущий», все будет работать нормально. Пожалуйста, обновите решение соответствующим образом. Спасибо

Ankur Raiyani 01.08.2020 17:11

Пример stackblitz не меняет страницу при нажатии на номер страницы. Пожалуйста, обновите его.

Mr Khan 09.08.2020 17:49

Цифры ничего не меняют на столе

Mr Khan 20.08.2020 12:18
stackblitz.com/edit/material-angular-paginator-customized Здесь прикреплена таблица с разбивкой на страницы. Посмотрите, сможете ли вы исправить эту разбивку на страницы номеров.
Mr Khan 20.08.2020 12:57

@MrKhan и Ankur благодарим вас за то, что обратили на это мое внимание. Я смог воспроизвести проблему и предоставил пересмотренный stackblitz выше. Это не самый элегантный код, но он должен быть близок к рабочему примеру ... пожалуйста, дайте мне знать, если вы обнаружите какие-либо дополнительные проблемы.

Marshal 21.08.2020 05:48

@ Маршал добро пожаловать. Не могли бы вы подробнее рассказать о внесенных вами изменениях? Также числа по-прежнему не работают при нажатии

Mr Khan 21.08.2020 06:28

@MrKhan Я снова поправил числа, сломал их, работая над рендерингом кнопок. Мне нужно пересмотреть алгоритм, который вычисляет диапазон, рендеринг кнопок по-прежнему очень глючит, я отправлю это завтра как-нибудь. Я попытаюсь внести в список изменений, но пока что это была значительная переработка. Вы можете сравнить старый stackblitz с новым для сравнения.

Marshal 21.08.2020 07:44

Конечно, @Marshal, это будет действительно полезно. Спасибо за ваше время и усилия :)

Mr Khan 21.08.2020 07:46

Привет, @MrKhan, я думаю, что все разобрал, и пересмотренная ссылка на stackblitz доступна для просмотра.

Marshal 21.08.2020 21:19

Это идеальный @Marshal. Большое спасибо!

Mr Khan 23.08.2020 11:56

HI @Marshal, это очень полезно, спасибо, можно ли показывать общее количество страниц после ... кнопок вместо кнопок firstlast?

Soumya Gangamwar 10.12.2020 08:45

За один раз я хочу использовать 5 кнопок, поэтому, если я пропущу [showTotalPages] = "5" после события pagegap, он покажет только 4 кнопки, а через 2 раза даже пропустит 2 кнопки, как это исправить?

Soumya Gangamwar 14.12.2020 07:56

Я разработал его таким образом, чтобы активная кнопка всегда находилась посередине. Я мог бы настроить это так, чтобы его можно было отключить, скорее всего, это будет позже на неделе, прежде чем я смогу выполнить рефакторинг, обновлю ответ, когда он будет доступен.

Marshal 14.12.2020 15:03

@Marshal это решение идеально. Но здесь у меня есть проблемы. Когда pageSize равен 5, я выбираю pageIndex 4 (page5). Когда я перехожу на размер страницы 10, pageIndex равен 2 (страница 3). как я могу настроить его, когда я изменяю pageSize, pageIndex всегда возвращается к 0 (первая страница)

TLVF2627 07.10.2021 16:37

Маршал неверен. Вы можете установить свойство pageIndex для пагинатора материалов. https://material.angular.io/components/paginator/api#MatPaginator

Я в точности имитировал то, что вы пытались сделать. Жестко запрограммирован, поэтому вам нужно будет выяснить, как добавлять кнопки в зависимости от количества страниц, но готово.

<button mat-fab (click) = "page.previousPage()"><</button>
          <button mat-fab (click) = "page.pageIndex = 0">1</button>
          <button mat-fab (click) = "page.pageIndex = 1">2</button>
          <button mat-fab (click) = "page.pageIndex = 2">3</button>
          <button mat-fab (click) = "page.nextPage()">></button>
          <mat-paginator style = "visibility:hidden" #page [length] = "100" [pageSize] = "10" [pageSizeOptions] = "[5, 10, 25, 100]"></mat-paginator>

Здесь вы можете найти мою настраиваемую директиву (StylePaginatorDirective), вдохновленную ответом @Marshal, но полностью переписанную с нуля, чтобы показать разбивку на страницы внутри mat-paginator-range-label

Предварительный просмотр

Stackblitz

https://stackblitz.com/edit/angular-wyx2ue-ayitwa?file=app%2Fstyle-paginator.directive.ts

https://angular-wyx2ue-ayitwa.stackblitz.io

Позиционирование

Не стесняйтесь настраивать порядок своих компонентов с помощью настраиваемого класса css: https://stackoverflow.com/a/55969038/2835268

Вставьте кнопки из mat-paginator Я думаю, что это невозможно, но вы можете создать собственный пейджер:

paginator-configurable-example.html

  <button mat-button (click) = "page.previousPage()"><</button>
  <button mat-button (click) = "updateManualPage(1)" >1</button>
  <button mat-button (click) = "updateManualPage(2)">2</button>
  <button mat-button (click) = "updateManualPage(3)">3</button>
  <button mat-button (click) = "page.nextPage()">></button>

  <mat-paginator style = "visibility:hidden" [pageIndex] = "pageIndex" #page [length] = "100" [pageSize] = "10" [pageSizeOptions] = "[5, 10, 25, 100]" (page) = "pageEvent = $event" ></mat-paginator>

<div *ngIf = "pageEvent">
  <h5>Page Change Event Properties</h5>
  <div>List length: {{pageEvent.length}}</div>
  <div>Page size: {{pageEvent.pageSize}}</div>
  <div>Page index: {{pageEvent.pageIndex}}</div>
</div>

paginator-configurable-example.ts

import {Component} from '@angular/core';
import {PageEvent} from '@angular/material/paginator';

/**
 * @title Configurable paginator
 */
@Component({
  selector: 'paginator-configurable-example',
  templateUrl: 'paginator-configurable-example.html',
  styleUrls: ['paginator-configurable-example.css'],
})
export class PaginatorConfigurableExample {
  // MatPaginator Inputs
  length = 100;
  pageSize = 10;
  pageSizeOptions: number[] = [5, 10, 25, 100];
  manualPage = null;

  // MatPaginator Output
  pageEvent: PageEvent;

  setPageSizeOptions(setPageSizeOptionsInput: string) {
    this.pageSizeOptions = setPageSizeOptionsInput.split(',').map(str => +str);
  }

  public updateManualPage(index: number): void {
    this.manualPage = index;
    this.pageEvent.pageIndex = index;
  }
  public clearManualPage(): void {
    this.manualPage = 0;
  }
}

example image

С помощью @Marshal я создал директиву для разбивки на страницы с точечным пробелом.

Скопируйте этот код в свою директиву

import {
  AfterViewInit,
  Directive,
  DoCheck,
  Host,
  Optional,
  Renderer2,
  Self,
  ViewContainerRef,
} from '@angular/core';
import { MatPaginator } from '@angular/material';

@Directive({
  selector: '[appStylePaginator]',
})
export class StylePaginatorDirective implements AfterViewInit, DoCheck {
  public currentPage = 1;
  public directiveLoaded = false;
  public pageGapTxt = '...';
  constructor(
    @Host() @Self() @Optional() private readonly matPag: MatPaginator,
    private readonly vr: ViewContainerRef,
    private readonly ren: Renderer2,
  ) {}

  private buildPageNumbers(pageCount, pageRange) {
    let dots = false;
    const paglast = pageCount;
    const pagcurrent = this.matPag.pageIndex;
    const showTotalPages = 8;
    for (let i = 0; i < paglast; i = i + 1) {
      if (
        i === pagcurrent ||
        (pagcurrent < showTotalPages && i < showTotalPages) ||
        (i > pagcurrent - (showTotalPages - 1) && i < pagcurrent) ||
        i > paglast - 1 ||
        (i > pagcurrent && i < pagcurrent + showTotalPages)
      ) {
        this.ren.insertBefore(pageRange, this.createPage(i, this.matPag.pageIndex), null);
      } else {
        if (i > pagcurrent && !dots) {
          this.ren.insertBefore(pageRange, this.createPage(this.pageGapTxt, this.matPag.pageIndex), null);
          dots = true;
        }
      }
    }
  }

  private createPage(i: any, pageIndex: number): any {
    const linkBtn = this.ren.createElement('mat-button');
    this.ren.addClass(linkBtn, 'mat-icon-button');

    const pagingTxt = isNaN(i) ? this.pageGapTxt : +(i + 1);
    const text = this.ren.createText(pagingTxt + '');
    this.ren.addClass(linkBtn, 'mat-custom-page');

    switch (i) {
      case pageIndex:
        this.ren.setAttribute(linkBtn, 'disabled', 'disabled');
        break;
      case this.pageGapTxt:
        this.ren.setAttribute(linkBtn, 'disabled', 'disabled');
        break;
      default:
        this.ren.listen(linkBtn, 'click', () => {
          this.currentPage = i;
          this.switchPage(i);
        });
        break;
    }

    this.ren.appendChild(linkBtn, text);
    return linkBtn;
  }

  private initPageRange(): void {
    const pagingContainerMain = this.vr.element.nativeElement.querySelector('.mat-paginator-range-actions');

    if (
      this.vr.element.nativeElement.querySelector('div.mat-paginator-range-actions div.btn_custom-paging-container')
    ) {
      this.ren.removeChild(
        pagingContainerMain,
        this.vr.element.nativeElement.querySelector('div.mat-paginator-range-actions div.btn_custom-paging-container'),
      );
    }

    const pagingContainerBtns = this.ren.createElement('div');
    const refNode = this.vr.element.nativeElement.childNodes[0].childNodes[0].childNodes[2].childNodes[5];
    this.ren.addClass(pagingContainerBtns, 'btn_custom-paging-container');
    this.ren.insertBefore(pagingContainerMain, pagingContainerBtns, refNode);

    const pageRange = this.vr.element.nativeElement.querySelector(
      'div.mat-paginator-range-actions div.btn_custom-paging-container',
    );
    pageRange.innerHtml = '';
    const pageCount = this.pageCount(this.matPag.length, this.matPag.pageSize);
    this.buildPageNumbers(pageCount, pageRange);
  }

  private pageCount(length: number, pageSize: number): number {
    return Math.floor(length / pageSize) + 1;
  }

  private switchPage(i: number): void {
    this.matPag.pageIndex = i;
    this.matPag._changePageSize(this.matPag.pageSize);
  }

  public ngAfterViewInit() {
    setTimeout(() => {
      this.directiveLoaded = true;
    }, 500);
  }

  public ngDoCheck() {
    if (this.directiveLoaded) {
      this.initPageRange();
    }
  }
}

После этого вам просто нужно добавить эту директиву в entryComponents нашего модуля.

Используйте это как:

<mat-paginator
  appStylePaginator //<<== Use of directive
  (page) = "pageChangeEvent($event)"
  [length] = "pageLength"
  [pageSize] = "pageSize"
  showFirstLastButtons
>
</mat-paginator>

Теперь вывод:

Мне нужен пользовательский пагинатор с точками вперед и назад с эмиттером событий. Итак, я улучшил директиву @ маршала, устранив множество ошибок и изменив ее, чтобы она работала точно так же, как ngx-pagination.

Просто хотел поделиться на случай, если кому-то это понадобится, код здесь Ссылка репо

Custom Pagination

@ Маршал. Их было слишком много. Одна из основных ошибок, которые я заметил, - это неэффективный цикл for. Например, если количество страниц 3000, цикл запускается 3000 раз. Я исправил это вместе с другими ошибками. Я также написал тестовый файл, чтобы убедиться, что все работает правильно. github.com/AzizStark/angular-custom-material-paginator/blob/‌…

AzizStark 24.11.2020 13:39

Будет ли эта строка в вашем коде также зацикливаться, если есть 3000 элементов действий? github.com/AzizStark/angular-custom-material-paginator/blob/‌…

Marshal 24.11.2020 15:12

Нет, это просто итерация по элементам html. Я исправил эту проблему для цикла в этой строке. github.com/AzizStark/angular-custom-material-paginator/blob/‌…

AzizStark 24.11.2020 18:31

Другие вопросы по теме