1.需求描述
由于版本兼容型等问题,分页的插件在Angular中问题频出,因此,采用自定义一个Angular分页组件并在其他页面中使用它。具体实现如下:
2.实现过程
步骤 1:创建分页组件
首先,在Angular项目中创建一个名为"pagination"的组件。在终端中运行以下命令:
ng generate component pagination
步骤 2:在分页组件中添加代码
打开"pagination.component.ts"文件,添加以下代码:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-pagination',
templateUrl: './pagination.component.html',
})
export class PaginationComponent implements OnInit {
@Input() currentPage: number;//当前页
@Input() totalPages: number;//总页数
@Input() maxSize: any = 5; //最多显示几页
@Output() pageChanged = new EventEmitter<number>();
showPageList: Array<number> = []; //页码数组
showEndPage = 0; //要展示的最后页码
showBeginPage = 0;//要展示的起始页码
showLeftMoreStatus = false; //判断是否显示左省略号
showRightMoreStatus = false;//判断是否显示右省略号
constructor() { }
ngOnInit(): void { }
// 异步获取的数据,在ngOnChange里监听数据变化后再处理分页
ngOnChanges () {
this.initPages();
}
//根据最大页面数限制和当前页面的位置,初始化用于展示页面的变量
initPages() {
if (this.totalPages > this.maxSize) { //检查总页面数是否大于最大页面,如果说总页面数就小于页面上要显示的最大页面数就不用继续往下处理了
this.maxSize--; //确保页面数量不超过最大数量
const startPage = this.currentPage;//开始展示的页面的页码
this.showBeginPage = startPage;//确定要展示的开始页面的页码
this.showEndPage = startPage + this.maxSize;//展示的结束页面的页码。
this.handlePagesData(startPage, this.showEndPage);//更新页码显示数组
}else{ //如果说页面总数小于设定的显示页面最大值,那么就循环页面数直接将其放在页码数组当中
this.showBeginPage = this.currentPage;
this.showEndPage = this.totalPages;
for(let i=1;i<this.totalPages;i++){
this.showPageList.push(i);
}
}
this.showPagesMore();//对于省略号的显示进行处理
}
// 循环生成要显示的页码数据
handlePagesData(begin, end) {
this.showPageList = [];
for (let i = begin; i <= end; i++) {
this.showPageList.push(i)
}
}
//如果总页数大于要显示的页码数,那么在操作页码以后,需要对新的页码数据进行处理
formatPages() {
if (this.totalPages > this.maxSize) {
const formatRightPage = this.showEndPage - Math.ceil(this.maxSize / 2); // 需要向后处理显示分页数据的分界点
const formatLeftPage = this.showBeginPage + Math.floor(this.maxSize / 2); // 需要向前处理显示分页数据的分界点
let startPage; // 需要显示的开始页码
if (this.currentPage > formatRightPage || this.currentPage < formatLeftPage) {
startPage = this.currentPage - Math.floor(this.maxSize / 2) > 0 ? this.currentPage - Math.floor(this.maxSize / 2) : 1;
this.showBeginPage = startPage;
this.showEndPage = (startPage + this.maxSize) < this.totalPages ? (startPage + this.maxSize) : this.totalPages;
if (this.showEndPage - this.showBeginPage <= this.maxSize) { // 如果处理后显示的分页数量少于maxSize,处理需要显示的开始页码满足maxSize
startPage = this.showEndPage - this.maxSize;
this.showBeginPage = startPage;
}
this.handlePagesData(startPage, this.showEndPage);
}
}
}
showPagesMore() { // 判断是否满足显示向左向右更多分页按钮的条件
if (this.currentPage > this.maxSize * 2) { //如果当前页码大于规定的显示页码总数的2倍这个时候就需要显示左边的省略号了,否则不显示
this.showLeftMoreStatus = true;
} else {
this.showLeftMoreStatus = false;
}
if (this.showEndPage < this.totalPages) { //如果当前显示页码的最大值小于总页数,这个时候就要显示右边的省略号了,否则不显示
this.showRightMoreStatus = true;
} else {
this.showRightMoreStatus = false;
}
}
goToPage(page) {
if (page && this.currentPage !== page) {
this.currentPage = page;
this.changePageHandle();
}
}
prevPage(pageNum: number){
if(pageNum===1){
this.currentPage = this.currentPage;
}else{
this.currentPage = this.currentPage-1
}
this.changePageHandle();
}
NextPage(pageNum: number){
if(pageNum===this.totalPages){
this.currentPage = this.currentPage;
}else{
this.currentPage = this.currentPage+1
}
this.changePageHandle();
}
changePageHandle() { // 翻页后触发方法
this.formatPages();
this.showPagesMore();
this.pageChanged.emit(this.currentPage);// 向外触发自定义方法,并传值
}
leftMoreClick(){
const startPage = this.showBeginPage - this.maxSize;
const endPage = startPage + this.maxSize;
this.currentPage -= Math.ceil((endPage - startPage) / 2);
this.changePageHandle()
}
rightMoreClick() { // 右更多分页按钮点击后处理当前显示的分页
let startPage;
if ((this.showEndPage + this.maxSize) < this.totalPages) {
startPage = this.showEndPage + this.maxSize;
} else {
startPage = this.totalPages - this.maxSize;
}
const endPage = startPage + this.maxSize;
this.currentPage += Math.ceil((endPage - startPage) / 2);
this.changePageHandle()
}
}
上述代码中,创建了一个带有输入和输出属性的分页组件。@Input()装饰器用于接收当前页码、总页码数等相关参数,@Output()装饰器用于触发页码更改事件。
步骤 3:创建分页组件的模板
打开"pagination.component.html"文件,并添加以下代码:
<ng-container>
<div class="row">
<div style="align-items: end;">
<nav aria-label="pageNavigation">
<ul class="pagination">
<li class="page-item prev-page" [ngClass]="{'disabled': currentPage == 1}">
<a class="page-link" (click)="prevPage(currentPage)"
aria-label="prePage">
<span aria-hidden="true">«</span>
</a>
</li>
<li *ngIf="showLeftMoreStatus" title="More">
<a class="page-link" (click)="leftMoreClick()"><span class="pagemore">...</span></a>
</li>
<li class="page-item" [ngClass]="{'active': item===currentPage}" *ngFor="let item of showPageList">
<a class="page-link" (click)="goToPage(item)"><span>{{item}}</span></a>
</li>
<li class="page-item" *ngIf="showLeftMoreStatus" title="More" [ngClass]="{'disabled': showEndPage>=totalPages}">
<a class="page-link" (click)="rightMoreClick()"><span class="pagemore">...</span></a>
</li>
<li class="page-item" [ngClass]="{'disabled': currentPage >= totalPages}">
<a class="page-link" (click)="NextPage(currentPage)"
aria-label="NextPage">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</ng-container>
上述代码创建了一个分页按钮组。使用了Angular内置的*ngFor指令来循环显示页码按钮。另外,在按钮上使用了一些条件属性绑定,以禁用当前页的按钮。
步骤 4:在需要使用分页的页面中引入组件
在想使用分页组件的html页面中,打开相应的组件模板文件,并添加以下代码:
<app-pagination [currentPage]="currentPage" [totalPages]="totalPages" (pageChanged)="onPageChanged($event)"></app-pagination>
步骤 5:在需要使用分页的页面所对应的ts中添加对应的变量及逻辑
export class TestComponent implements OnInit {
currentPage = 1;
pageSize :10;
totalPages = 1; //总页数
displayedData= []; //当前显示的数据
dataArray=[];//所有数据
constructor() {
}
async ngOnInit() {
this.totalPages = Math.ceil(this.dataArray.length / this.pageSize);
this.onPageChanged(this.currentPage);
}
onPageChanged(pageNumber: number) {
// 根据当前页码和每页显示的数量,计算数据在数组中的切片范围
const startIndex = (pageNumber - 1) * this.pageSize;
const endIndex = startIndex + this.pageSize;
// 更新其他相关属性,例如重新计算总页数
this.totalPages = Math.ceil(this.dataArray.length / this.pageSize);
// 使用数据数组的切片来更新表格的显示
this.displayedData = this.dataArray.slice(startIndex, endIndex);
}
}
这样,就可以在页面中使用自定义的分页组件了。记得在使用分页组件之前,确保定义了"currentPage"和"totalPages"属性,并实现了"onPageChanged()"方法。
最后实现效果:
大部分解释都在代码注释当中了,若有其他疑问欢迎在评论区留言。