Angular 实现分页器组件
很感谢 angular实现简单的pagination分页组件 - Amor丶Diamond - 博客园 (cnblogs.com) , 我根据这位博主代码做了修改, 增加了跳转和每页行数功能.
先看图:

// 可配置项
// totalItem 数据总条数
// maxSize:最多显示几页
// pageSizes: 行/页
// moreBtn:是否显示省略号提示更多分页
// turnBtn:是否显示上下翻页
// fastTurnBtn:是否显示首页和末页
// goToBtn: 是否显示跳转
// pageInfoIsShow: 是否显示总页数
// pageSizeIsShow: 是否显示 行/页, 如果关闭: 行/页 = 10
paginator.component.html:
<div>
<ul class="custom-pagination">
<li class="page-size" *ngIf="pageSizeIsShow">
行/页:<select [(ngModel)]="pageSize" (change)="selectItem()">
<option *ngFor="let item of pageSizes" [value]="item">{{ item }}</option>
</select>
</li>
<li class="page-item first-page" *ngIf="fastTurnBtn" [ngClass]="{'disabled': currentPage <= 1}"
(click)="goToPage(1)"><span><<</span></li>
<li class="page-item prev-page" *ngIf="turnBtn" [ngClass]="{'disabled': currentPage <= 1}"
(click)="preNextPage('上一页')"><span><</span></li>
<li class="page-item left-more-page" *ngIf="showLeftMoreStatus && moreBtn" (click)="leftMoreClick()"
title="查看更多">
<span></span></li>
<li class="page-item" *ngFor="let item of showPageList;" [ngClass]="{'active': item === currentPage}"
(click)="goToPage(item)">{{item}}</li>
<li class="page-item right-more-page" *ngIf="showRightMoreStatus && moreBtn" (click)="rightMoreClick()"
title="查看更多"><span></span></li>
<li class="page-item next-page" *ngIf="turnBtn" [ngClass]="{'disabled': currentPage >= totalPage}"
(click)="preNextPage('下一页')"><span>></span></li>
<li class="page-item last-page" *ngIf="fastTurnBtn" [ngClass]="{'disabled': currentPage >= totalPage}"
(click)="goToPage(totalPage)"><span>>></span></li>
<li class="page-goto" *ngIf="goToBtn">
<input type="number" [(ngModel)]="goToPageNum" min="1">
<button (click)="goToPage(goToPageNum)">跳转</button>
</li>
<li class="page-pageInfo" *ngIf="pageInfoIsShow"><span> 共 {{totalPage}} 页</span></li>
</ul>
</div>
paginator.component.ts
import {Component, OnInit, OnChanges, Input, Output, EventEmitter} from '@angular/core';
import {noop} from "rxjs";
@Component({
selector: 'my-paginator',
templateUrl: './paginator.component.html',
styleUrls: ['./paginator.component.scss']
})
export class PaginatorComponent implements OnInit, OnChanges {
// 可配置项
// totalItem 数据总条数
// maxSize:最多显示几页
// pageSizes: 行/页
// moreBtn:是否显示省略号提示更多分页
// turnBtn:是否显示上下翻页
// fastTurnBtn:是否显示首页和末页
// goToBtn: 是否显示跳转
// pageInfoIsShow: 是否显示总页数
// pageSizeIsShow: 是否显示 行/页, 如果关闭, 行/页 = 10
private static defaultTotalItem = 0;
private static defaultMaxSize = 10;
private static defaultPageSizes = [10, 15, 20, 25, 30];
private static defaultMoreBtn = true;
private static defaultTurnBtn = true;
private static defaultFastTurnBtn = true;
private static defaultGoToBtn = true;
private static defaultPageInfoIsShow = true;
private static defaultPageSizeIsShow = true;
private static defaultTotalPage = 0;
@Input() totalItem: number = PaginatorComponent.defaultTotalItem;
@Input() maxSize: number = PaginatorComponent.defaultMaxSize;
@Input() pageSizes = PaginatorComponent.defaultPageSizes;
@Input() moreBtn: Boolean = PaginatorComponent.defaultMoreBtn;
@Input() turnBtn: Boolean = PaginatorComponent.defaultTurnBtn;
@Input() fastTurnBtn: Boolean = PaginatorComponent.defaultFastTurnBtn;
@Input() goToBtn: Boolean = PaginatorComponent.defaultGoToBtn;
@Input() pageInfoIsShow: Boolean = PaginatorComponent.defaultPageInfoIsShow;
@Input() pageSizeIsShow: Boolean = PaginatorComponent.defaultPageSizeIsShow;
@Output() currentPageChange: EventEmitter<Number> = new EventEmitter;
@Output() pageSizeChange: EventEmitter<Number> = new EventEmitter;
private pageSize = PaginatorComponent.defaultPageSizes[0];
private currentPage = 1;
totalPage = 0;
goToPageNum = 1;
showPageList: Array<number> = [];
showEndPage = 0;
showBeginPage = 0;
showLeftMoreStatus = false;
showRightMoreStatus = false;
constructor() {
}
ngOnInit: () => void = noop;
ngOnChanges() {
this.initPages();
}
currentChange() {
this.currentPageChange.emit(this.currentPage);
}
preNextPage(page: string) {
if (this.totalPage <= 1) {
return;
}
let pageNum;
if (page === '上一页') {
if (this.currentPage <= 1) return;
pageNum = this.currentPage === 1 ? this.currentPage : this.currentPage - 1;
} else {
if (this.currentPage >= this.totalPage) return;
pageNum = this.currentPage === this.totalPage ? this.currentPage : this.currentPage + 1;
}
if (pageNum !== this.currentPage) {
this.currentPage = pageNum;
this.changePageHandle();
}
}
goToPage(page: number) {
if (page && this.currentPage !== page) {
if (0 <= page && page <= this.totalPage) {
this.currentPage = page;
} else if (page > this.totalPage) {
this.currentPage = this.totalPage;
} else {
this.currentPage = 1;
}
this.changePageHandle();
}
}
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.totalPage) {
startPage = this.showEndPage + this.maxSize;
} else {
startPage = this.totalPage - this.maxSize;
}
const endPage = startPage + this.maxSize;
this.currentPage += Math.ceil((endPage - startPage) / 2);
this.changePageHandle();
}
formatPages() {
const maxSizeHalf = this.maxSize / 2;
const maxSizeHalfFloor = Math.floor(maxSizeHalf);
const minBoundary = this.showEndPage - Math.ceil(maxSizeHalf); // 需要向后处理显示分页数据的分界点
const maxBoundary = this.showBeginPage + maxSizeHalfFloor; // 需要向前处理显示分页数据的分界点
if (this.currentPage > minBoundary || this.currentPage < maxBoundary) {
this.showBeginPage = this.currentPage - maxSizeHalfFloor > 1 ? this.currentPage - maxSizeHalfFloor : 1;
this.showEndPage = (this.showBeginPage + this.maxSize - 1) < this.totalPage ? (this.showBeginPage + this.maxSize - 1) : this.totalPage;
if (this.showEndPage - this.showBeginPage < this.maxSize - 1) {
this.showBeginPage = this.showEndPage - this.maxSize > 1 ? this.showEndPage - (this.maxSize - 1) : 1;
}
this.handlePagesData(this.showBeginPage, this.showEndPage);
}
// console.log(this.showPageList);
}
// 根据传入的参数初始化页码
initPages() {
// 初始化 pageSizes
if (this.pageSizeIsShow) {
for (let i = 0; i < this.pageSizes.length; i++) {
if (this.pageSizes[i] <= 0) {
this.pageSizes.splice(i, 1);
i--;
}
}
if (this.pageSizes.length === 0) {
this.pageSizes = PaginatorComponent.defaultPageSizes;
}
// 初始化 pageSize
this.pageSize = this.pageSizes[0];
}
if (this.totalItem >= 0 && this.maxSize >= 1) {
let startPage = 1;
this.showBeginPage = startPage;
this.showEndPage = startPage + this.maxSize - 1;
this.totalPage = Math.ceil(this.totalItem / this.pageSize);
if (this.totalPage < this.maxSize) {
this.showEndPage = this.totalPage;
}
} else {
// 如果初始值不正确, 就是用默认值, TODO 不显示
this.totalPage = PaginatorComponent.defaultTotalPage;
this.maxSize = PaginatorComponent.defaultMaxSize;
this.showBeginPage = 1;
this.showEndPage = 1;
}
this.handlePagesData(this.showBeginPage, this.showEndPage);
this.showPagesMore();
}
handlePagesData(begin, end) {
// 循环生成要显示的页码数据
this.showPageList = [];
for (let i = begin; i <= end; i++) {
this.showPageList.push(i);
}
}
showPagesMore() {
if (this.currentPage > this.maxSize * 2) {
this.showLeftMoreStatus = true;
} else {
this.showLeftMoreStatus = false;
}
if (this.showEndPage < this.totalPage) {
this.showRightMoreStatus = true;
} else {
this.showRightMoreStatus = false;
}
}
changePageHandle() {
// 翻页后触发方法
this.formatPages();
this.showPagesMore();
this.onModelChange(this.currentPage); // 触发ngModel绑定的数据更新
this.currentPageChange.emit(this.currentPage);
this.pageSizeChange.emit(this.pageSize);
}
onModelChange: Function = () => {
};
// 在选择一页显示多少行后就将值传回
selectItem() {
this.totalPage = Math.ceil(this.totalItem / this.pageSize);
this.currentPage = 1;
this.changePageHandle();
}
// 页面的值改变,调用改方法,并调用onModelChange传入改变后的值,实现值的回传
writeValue(val): void {
// 页面初始化时时,调用该方法,传入初始值
if (val) {
this.currentPage = val;
}
}
registerOnChange(fn: any): void {
// 页面值改变时,调用该方法,传入新值实现回传
this.onModelChange = fn;
}
registerOnTouched(fn: any): void {
}
protected readonly print = print;
protected readonly console = console;
}
paginator.component.scss
// custom-pagination.css
.custom-pagination {
overflow: hidden;
margin: 10px 0;
text-align: center;
} .page-size {
display: inline-block;
height: 25px;
line-height: 23px;
border-radius: 3px;
margin: 0 15px;
cursor: pointer;
user-select: none;
vertical-align: middle;
} input {
width: 30px;
} .page-item {
display: inline-block;
width: 25px;
height: 25px;
line-height: 23px;
border: 1px solid #06a0e7;
color: #06a0e7;
text-align: center;
border-radius: 3px;
margin: 0 2px;
cursor: pointer;
user-select: none;
vertical-align: middle;
} .page-goto {
display: inline-block;
height: 25px;
line-height: 23px;
text-align: center;
border-radius: 3px;
margin: 0 15px;
cursor: pointer;
user-select: none;
vertical-align: middle;
}
.page-pageInfo{
display: inline-block;
}
.prev-page, .next-page {
width: auto;
padding: 0 2px;
} .page-item.active, .page-goto.active {
border-color: #06a0e7;
background: #06a0e7;
color: #fff;
} .disabled {
cursor: not-allowed;
border-color: #d9d9d9;
color: #00000040;
} .prev-page span, .next-page span, .first-page span, .last-page span {
display: inline-block;
transform: scale(.5, 1.2) translateY(-1px);
min-width: 20px;
} .left-more-page span, .right-more-page span {
position: relative;
display: inline-block;
width: 100%;
height: 100%;
} .left-more-page span:after, .right-more-page span:after {
position: absolute;
content: '•••';
width: 100%;
height: 100%;
left: 0;
top: 0;
font-size: 12px;
} .left-more-page:hover span:after {
content: '<<';
transform: scale(.5, 1.2);
} .right-more-page:hover span:after {
content: '>>';
transform: scale(.5, 1.2);
}
转载请说明注明作者: 书源
Angular 实现分页器组件的更多相关文章
- Angular4 后台管理系统搭建(1) - 建立一个通用的Wijmo5 flexgrid分页器组件
17年4月,开始学习angular2,到5月跟着升级到angular4.目前还在学习,搭建中.我的最终目的是用angular4框架搭建一个后台管理系统.这里使用了三个关键的外部库. 1.使用admin ...
- Angular动态创建组件之Portals
这篇文章主要介绍使用Angular api 和 CDK Portals两种方式实现动态创建组件,另外还会讲一些跟它相关的知识点,如:Angular多级依赖注入.ViewContainerRef,Por ...
- django -----分页器组件
分页器组件 本文目录 1 Django的分页器(paginator)简介 2 应用View层 3 模版层 index.html 4 扩展 回到目录 1 Django的分页器(paginator)简介 ...
- dj 分页器组件
django内置的分页器组件,能够帮我们实现对查询的数据进行自动分页,并返回分页对象 from django.core.paginator import Paginator, EmptyPage Pa ...
- django中的分页器组件
目录 django的组件-分页器 引入分页器 分页器demo 创建数据库模型 url控制器 views视图函数 templates模板 为什么要用分页器 导入分页器 分页器优化1 分页器优化2 有多少 ...
- angular 有关侦测组件变化的 ChangeDetectorRef 对象
我们知道,如果我们绑定了组件数据到视图,例如使用 <p>{{content}}</p>,如果我们在组件中改变了content的值,那么视图也会更新为对应的值. angular ...
- 基于django做增删改查组件,分页器组件
增删改查组件 一.Djangoadmin的启发 二.基于Djangoadmin实现数据的增删改查 分页器组件 分页器组件的介绍以及源码解读 补充:源码下载,
- django url注册器组件, 响应器组件, 分页器组件
一.url注册器的使用 1.1导入模块 from django.urls import re_path, include from .serializer import views from rest ...
- rest认证组件,权限组件,频率组件,url注册器,响应器组件,分页器组件
1.认证组件 1.1 认证组件利用token来实现认证 1.2 token认证的大概流程 用户登录===>获取用户名和密码===>查询用户表 如果用户存在,生成token,否则返回错误信息 ...
- 【Angular】关于angular引用第三方组件库无法改变其组件样式 :host ::ng-deep
[Angular]关于angular引用第三方组件库无法改变其组件样式 :host ::ng-deep css修改:无效 .ant-input-affix-wrapper .ant-input:not ...
随机推荐
- strimzi实战之三:prometheus+grafana监控(按官方文档搞不定监控?不妨看看本文,已经踩过坑了)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 由于整个系列的实战都涉及到消息生产和消费,所 ...
- SpringBoot进阶 CommandLineRunner 初始化配置
在Spring Boot中,CommandLineRunner接口用于在应用程序启动后执行一些特定的命令行操作.通过实现CommandLineRunner接口,您可以在Spring Boot应用程序运 ...
- LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题
️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...
- 采用ResNet网络+TSNE降维算法对自建图像数据集进行二维可视化显示
起因:某一天下午,我在"玩"的时候,突然接到了老板的电话,说是要对图像做可视化降维.因此,我拿到了一批图像的数据. 数据的特点: 1.数据集的图像分为4类,并且每一种类的图像多少不 ...
- CF1534C
题目简化和分析: 涉及算法:并查集. 为什么要使用并查集: 因为交换只能是列交换,并且保证不与别的重复 我们通过观察题目发现,某些列之间互为限制关系 即如果某列序列排序方式固定,则被限制的列也为固定的 ...
- Windows下VC++编译器32位memcpy、memmove函数汇编代码详解
整理者:赤勇玄心行天道 QQ号:280604597 微信号:qq280604597 QQ群:511046632 博客:www.cnblogs.com/gaoyaguo blog.csdn.net/c ...
- C++函数如何具有多个返回值?
本文介绍在C++语言中,使用一个函数,并返回两个及以上.同类型或不同类型的返回值的具体方法. 对于C++语言而言,其不能像Python等语言一样在一个函数中返回多个返回值:但是我们也会经常遇到 ...
- CSP2023 模拟赛总结合集
9.9 ZZFLS 感觉 ucup 剩下的题完全不可做了啊!先对比赛时间来写总结对队友道歉(鞠躬.jpg 开题策略很失败.开场 30min 得的分数是一整场考试的分数. 开题,发现 T1 是水题,30 ...
- IoC容器趣谈
今天我们来谈谈Spring的内核之一--IoC容器 大家可能会有这样的疑问: "这玩意为啥要叫容器呢?好奇怪" "容器不是装东西的吗?难道IoC容器也是用来装什么东西的? ...
- Python 利用pandas和matplotlib绘制堆叠柱状图
在数据可视化中,堆叠柱状图是一种常用的图表类型,它能够清晰地展示多个类别的数据,并突出显示每个类别中各部分的总量和组成比例.本文将演示如何使用 Python 的 pandas 和 matplotlib ...