很感谢 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. Mybatisplus3.5.1+shardingsphere-jdbc5.1.1分表

    注意使用雪花ID的话,查询ID时候必须使用long类型的ID,不要使用MP自带的默认的Serializable类型.否则会提示分片主键id数据类型和分片算法不匹配Inline sharding alg ...

  2. ElasticSearch系列——倒排索引、删除映射类型、打分机制、配置文件、常见错误

    文章目录 1 倒排索引 2 删除映射类型 一 前言 二 什么是映射类型? 三 为什么要删除映射类型? 四 映射类型的替代方法 4.1 将映射类型分开存储在索引中 4.2 自定义类型字段回到顶部 五 没 ...

  3. 征集 meme

    当你每次兴致勃勃地和好友分享自己喜欢的歌但 Ta 不屑一顾 / 不喜欢时:

  4. [SWPUCTF 2021 新生赛]老鼠走迷宫(详细版

    附件下载 https://wwvc.lanzouj.com/iYLez1br84jg 解题思路 用pyinstxtrator解析exe 重点:将无后缀的5先修改后缀为pyc,然后随便找一个pyc文件补 ...

  5. Kafka的零拷贝技术Zero-Copy

    传统的拷贝过程 流程步骤: (1)操作系统将数据从磁盘文件中读取到内核空间的页面缓存: (2)应用程序将数据从内核空间读入用户空间缓冲区: (3)应用程序将读到数据写回内核空间并放入socket缓冲区 ...

  6. 基于LangChain的LLM应用开发3——记忆

    此情可待成追忆,只是当时已惘然.我们人类会有很多或美好或痛苦的回忆,有的回忆会渐渐模糊,有的回忆午夜梦醒,会浮上心头. 然而现在的大语言模型都是没有记忆的,都是无状态的,大语言模型自身不会记住和你对话 ...

  7. 带着问题去分析:Spring Bean 生命周期

    1: Bean在Spring容器中是如何存储和定义的 Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_ ...

  8. 关于虚拟机的IP地址经常改变问题的解法

    主要解法就是配置静态IP地址 首先了解一下IP和子网掩码,网关的含义:IP 是标识计算机特定地址的二进制数,子网掩码用于和IP组合划分子网;网关是将信息传送到网关进行收发 开始配置:首先打开Linux ...

  9. 探究-ping指令的使用

    简介: 背景:一直以来在项目上经常使用ping指令来测试网络通信,最近稍微研究了一下常用的指令,记录以作备忘.--MaQaQ 2023-11-1 ping (Packet Internet Grope ...

  10. 把 map 中的 key 由驼峰命名转为下划线

    import cn.hutool.core.util.StrUtil; /** * 把 map 中的 key 由驼峰命名转为下划线 */public HashMap<String, Object ...