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

ОБНОВИТЬ 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
Спасибо за это решение. Я пробовал, но когда я нажимаю на номер страницы, страница не меняется. Кроме того, если я нажму кнопку «Далее и предыдущий», все будет работать нормально. Пожалуйста, обновите решение соответствующим образом. Спасибо
Пример stackblitz не меняет страницу при нажатии на номер страницы. Пожалуйста, обновите его.
Цифры ничего не меняют на столе
@MrKhan и Ankur благодарим вас за то, что обратили на это мое внимание. Я смог воспроизвести проблему и предоставил пересмотренный stackblitz выше. Это не самый элегантный код, но он должен быть близок к рабочему примеру ... пожалуйста, дайте мне знать, если вы обнаружите какие-либо дополнительные проблемы.
@ Маршал добро пожаловать. Не могли бы вы подробнее рассказать о внесенных вами изменениях? Также числа по-прежнему не работают при нажатии
@MrKhan Я снова поправил числа, сломал их, работая над рендерингом кнопок. Мне нужно пересмотреть алгоритм, который вычисляет диапазон, рендеринг кнопок по-прежнему очень глючит, я отправлю это завтра как-нибудь. Я попытаюсь внести в список изменений, но пока что это была значительная переработка. Вы можете сравнить старый stackblitz с новым для сравнения.
Конечно, @Marshal, это будет действительно полезно. Спасибо за ваше время и усилия :)
Привет, @MrKhan, я думаю, что все разобрал, и пересмотренная ссылка на stackblitz доступна для просмотра.
Это идеальный @Marshal. Большое спасибо!
HI @Marshal, это очень полезно, спасибо, можно ли показывать общее количество страниц после ... кнопок вместо кнопок firstlast?
За один раз я хочу использовать 5 кнопок, поэтому, если я пропущу [showTotalPages] = "5" после события pagegap, он покажет только 4 кнопки, а через 2 раза даже пропустит 2 кнопки, как это исправить?
Я разработал его таким образом, чтобы активная кнопка всегда находилась посередине. Я мог бы настроить это так, чтобы его можно было отключить, скорее всего, это будет позже на неделе, прежде чем я смогу выполнить рефакторинг, обновлю ответ, когда он будет доступен.
@Marshal это решение идеально. Но здесь у меня есть проблемы. Когда pageSize равен 5, я выбираю pageIndex 4 (page5). Когда я перехожу на размер страницы 10, pageIndex равен 2 (страница 3). как я могу настроить его, когда я изменяю pageSize, pageIndex всегда возвращается к 0 (первая страница)
Маршал неверен. Вы можете установить свойство 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;
}
}
С помощью @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.
Просто хотел поделиться на случай, если кому-то это понадобится, код здесь Ссылка репо
@ Маршал. Их было слишком много. Одна из основных ошибок, которые я заметил, - это неэффективный цикл for. Например, если количество страниц 3000, цикл запускается 3000 раз. Я исправил это вместе с другими ошибками. Я также написал тестовый файл, чтобы убедиться, что все работает правильно. github.com/AzizStark/angular-custom-material-paginator/blob/…
Будет ли эта строка в вашем коде также зацикливаться, если есть 3000 элементов действий? github.com/AzizStark/angular-custom-material-paginator/blob/…
Нет, это просто итерация по элементам html. Я исправил эту проблему для цикла в этой строке. github.com/AzizStark/angular-custom-material-paginator/blob/…
Хорошо. Спасибо за помощь @Marshal