Mat-paginatorをカスタマイズしたいと思います。デフォルトでは、以下のリンク https://material.angular.io/components/paginator/overview で指定されているこのようなページネーターを取得しています。しかし、私は下の画像のようなページネーションが欲しいです。 mat-paginatorを使用してこれを行う方法
誰かがこれを手伝ってくれませんか?.
@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>
[〜#〜]更新[〜#〜]2020年2月27日
@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
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;
}
}
元帥は正しくない。マテリアルパジネーターの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>
@Marshalによって提供された回答に触発された私のカスタムディレクティブ(StylePaginatorDirective)をここに見つけることができますが、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