很感谢 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">
&nbsp;<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 实现分页器组件的更多相关文章

  1. Angular4 后台管理系统搭建(1) - 建立一个通用的Wijmo5 flexgrid分页器组件

    17年4月,开始学习angular2,到5月跟着升级到angular4.目前还在学习,搭建中.我的最终目的是用angular4框架搭建一个后台管理系统.这里使用了三个关键的外部库. 1.使用admin ...

  2. Angular动态创建组件之Portals

    这篇文章主要介绍使用Angular api 和 CDK Portals两种方式实现动态创建组件,另外还会讲一些跟它相关的知识点,如:Angular多级依赖注入.ViewContainerRef,Por ...

  3. django -----分页器组件

    分页器组件 本文目录 1 Django的分页器(paginator)简介 2 应用View层 3 模版层 index.html 4 扩展 回到目录 1 Django的分页器(paginator)简介 ...

  4. dj 分页器组件

    django内置的分页器组件,能够帮我们实现对查询的数据进行自动分页,并返回分页对象 from django.core.paginator import Paginator, EmptyPage Pa ...

  5. django中的分页器组件

    目录 django的组件-分页器 引入分页器 分页器demo 创建数据库模型 url控制器 views视图函数 templates模板 为什么要用分页器 导入分页器 分页器优化1 分页器优化2 有多少 ...

  6. angular 有关侦测组件变化的 ChangeDetectorRef 对象

    我们知道,如果我们绑定了组件数据到视图,例如使用 <p>{{content}}</p>,如果我们在组件中改变了content的值,那么视图也会更新为对应的值. angular ...

  7. 基于django做增删改查组件,分页器组件

    增删改查组件 一.Djangoadmin的启发 二.基于Djangoadmin实现数据的增删改查 分页器组件 分页器组件的介绍以及源码解读 补充:源码下载,

  8. django url注册器组件, 响应器组件, 分页器组件

    一.url注册器的使用 1.1导入模块 from django.urls import re_path, include from .serializer import views from rest ...

  9. rest认证组件,权限组件,频率组件,url注册器,响应器组件,分页器组件

    1.认证组件 1.1 认证组件利用token来实现认证 1.2 token认证的大概流程 用户登录===>获取用户名和密码===>查询用户表 如果用户存在,生成token,否则返回错误信息 ...

  10. 【Angular】关于angular引用第三方组件库无法改变其组件样式 :host ::ng-deep

    [Angular]关于angular引用第三方组件库无法改变其组件样式 :host ::ng-deep css修改:无效 .ant-input-affix-wrapper .ant-input:not ...

随机推荐

  1. Oracle:Ora-01652无法通过128(在temp表空间中)扩展temp段的过程-解决步骤

    现象:查询select * from v$sql时提示"Ora-01652无法通过128(在temp表空间中)扩展temp段的过程" 临时文件是不存储的,可以将数据库重启,重启后重 ...

  2. 解密IP分片与重组:数据传输中的关键技术

    引言 在上一章节中,我们详细讨论了IP的分类和无分类原则的原理以及其在网络通信中的应用.IP分片与重组是在数据包传输过程中起到关键作用的机制.当数据包的大小超过网络链路的MTU(最大传输单元)限制时, ...

  3. linux文件、目录权限和所有者

    文件.目录权限和所有者 简介:用户对一个文件或目录具有访问权限,这些访问权限决定了谁能访问,以及如何范围这些文件和目录.通过设置权限可以限制或允许以下三种用户访问: 文件的用户所有者(属主) 文件的组 ...

  4. OI-note

    版权声明:仅供学习. 持续更新中...也算是个人学习的监督与激励吧. OI路漫漫,且行且珍惜. OI太颓了,模拟赛都打不动,班级全是大佬. 算法综合 \(Algorithm\) 杂题综合 Index ...

  5. 如何用CRM销售管理系统实现销售目标?

    每个企业的销售业务都要制定目标计划,在制定销售计划时要考虑两个问题,一个是计划是否能够严格执行,另一个是计划是否可控,即明确销售目标后,合理分配时间,运用销售基本工作方法严格把控销售进度.那我们该如何 ...

  6. Vue之属性

    Vue中的属性:举例 看一下就明白了 <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  7. 使用aop(肉夹馍)为BlazorServer实现统一异常处理

    背景 用户做一个操作往往对应一个方法的执行,而方法内部会调用别的方法,内部可能又会调用别的方法,从而形成一个调用链.我们一般是在最顶层的方法去加try,而不是调用链的每一层都去加try. 在web开发 ...

  8. QT(4)-QAbstractItemView

    @ 目录 1 说明 2 常用函数 2.1 交替行颜色 2.1.1 alternatingRowColors 2.1.2 setAlternatingRowColors 2.2 autoScroll 2 ...

  9. Spring3.0中的AOP配置方法

    http://zywang.iteye.com/blog/974226 http://www.cnblogs.com/garinzhang/p/java_spring_aop_aspect.html ...

  10. Soc的Bring Up流程

    1.Bring Up流程 SOC (System on a Chip) bring-up是一个复杂的过程,涉及到硬件.固件和软件的集成和验证,以下是一个基于BROM,SPL,UBOOT和Linux的启 ...