angular实现简单的pagination分页组件
不想使用第三方库,只想使用一个分页器,那么就简单的实现一个,效果如下:

1.使用方式:
<custom-pagination *ngIf="enterpriseList.length"
[fastTurnBtn]="false"
[totalPage]="paginationParams.totalPages"
[maxSize]="paginationParams.maxSize"
[(ngModel)]="paginationParams.currentPage"
(changePage)="changePage($event)">
</custom-pagination>
2.可配置项:
- fsatTurnBtn:是否显示首页和末页
- turnBtn:是否显示上下翻页
- maxSize:最多显示几页
- totalPage:总页数
- moreBtn:是否显示省略号提示更多分页
3.实现方案:
先上代码,这里使用啦ngModel实现自定义组件的数据双向绑定,可以看上一篇随记的介绍:
// custom-pagination.ts
import { Component, OnInit, Input, Output, EventEmitter, OnChanges, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'custom-pagination',
templateUrl: './pagination.component.html',
styleUrls: ['./pagination.component.css'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PaginationComponent),
multi: true
}]
})
export class PaginationComponent implements OnInit, OnChanges {
constructor() { }
@Input() totalPage: any;
@Input() maxSize: any = 5;
@Input() moreBtn: Boolean = true;
@Input() turnBtn: Boolean = true;
@Input() fastTurnBtn: Boolean = true;
@Output() currentPageChange: EventEmitter<Number> = new EventEmitter;
@Output() changePage: EventEmitter<Number> = new EventEmitter;
private currentPage = 1;
showPageList: Array<number> = [];
showEndPage = 0;
showBeginPage = 0;
showLeftMoreStatus = false;
showRightMoreStatus = false;
ngOnInit() {
}
ngOnChanges () { // 异步获取的数据,在ngOnChange里监听数据变化后再处理分页
this.initPages();
}
currentChange() {
this.currentPageChange.emit(this.currentPage);
}
goToPage (page) {
if (page && this.currentPage !== page) {
this.currentPage = page;
this.changePageHandle();
}
}
prevNextPage (page) {
console.log(this.currentPage)
if (this.totalPage < 2) {
return;
}
let pageNum;
if (page === '上一页') {
pageNum = this.currentPage === 1 ? this.currentPage : this.currentPage - 1;
} else {
pageNum = this.currentPage === this.totalPage ? this.currentPage : this.currentPage + 1;
}
if (pageNum !== this.currentPage) {
this.currentPage = pageNum;
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 () { // 操作页码后处理需要显示的新页码数据
if (this.totalPage > 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.totalPage ? (startPage + this.maxSize) : this.totalPage;
if (this.showEndPage - this.showBeginPage <= this.maxSize) { // 如果处理后显示的分页数量少于maxSize,处理需要显示的开始页码满足maxSize
startPage = this.showEndPage - this.maxSize;
this.showBeginPage = startPage;
}
this.handlePagesData(startPage, this.showEndPage);
}
}
console.log(this.showPageList)
}
initPages () { // 根据传入的参数初始化页码
if (this.totalPage > 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.totalPage;
for (let i = 1; i <= this.totalPage; i++) {
this.showPageList.push(i)
}
}
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.changePage.emit(this.currentPage); // 向外触发自定义方法,并传值
}
onModelChange: Function = () => { };
// 页面的值改变,调用改方法,并调用onModelChange传入改变后的值,实现值得回传
writeValue(val): void {
// 页面初始化时时,调用该方法,传入初始值
if (val) {
this.currentPage = val;
}
}
registerOnChange(fn: any): void {
// 页面值改变时,调用该方法,传入新值实现回传
this.onModelChange = fn;
}
registerOnTouched(fn: any): void {
}
}
<!--custom-pagination.html--> <ul class="custom-pagination">
<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)="prevNextPage('上一页')"><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': currentPage === item}" (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)="prevNextPage('下一页')"><span>></span></li>
<li class="page-item last-page" *ngIf="fastTurnBtn" [ngClass]="{'disabled': currentPage === totalPage}" (click)="goToPage(totalPage)"><span>>></span></li>
</ul>
// custom-pagination.css
.custom-pagination{
overflow: hidden;
margin: 10px 0;
text-align: center;
}
.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;
}
.prev-page,.next-page{
width: auto;
padding: 0 2px;
}
.page-item.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:;
top:;
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实现简单的pagination分页组件的更多相关文章
- 手把手教你使用Vue/React/Angular三大框架开发Pagination分页组件
DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师.官方网站:devui.designNg组件库:ng-devui(欢迎S ...
- 第二百零九节,jQuery EasyUI,Pagination(分页)组件
jQuery EasyUI,Pagination(分页)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Pagination(分页)组件的使 ...
- Vue 2.0 pagination分页组件
最近写了一个分页组件,效果如下图: f-pagination.js文件 Vue.component('f-pagination',{ template:'<div class="fPa ...
- EasyUI - pagination 分页组件
总页数是手动填写,后续进行更改……………… 效果: html代码: <!--使用标签创建--> <%--<div id="pp" class="e ...
- Angular4.+ ngx-bootstrap Pagination 自定义分页组件
Angular4 随笔(二) ——自定义分页组件 1.简介 本组件主要是实现了分页组件显示功能,通过使用 ngx-bootstrap Pagination分页组件实现. 基本逻辑: 1.创建一个分页 ...
- 基于Vue.js的表格分页组件
有一段时间没更新文章了,主要是因为自己一直在忙着学习新的东西而忘记分享了,实在惭愧. 这不,大半夜发文更一篇文章,分享一个自己编写的一个Vue的小组件,名叫BootPage. 不了解Vue.js的童鞋 ...
- angular-ui分页组件
http://angular-ui.github.io/bootstrap/#/pagination 分页组件只提供生成分页按钮,数据的显示需要使用ng-repeat, 注意设置 items-per- ...
- 基于Vue封装分页组件
使用Vue做双向绑定的时候,可能经常会用到分页功能 接下来我们来封装一个分页组件 先定义样式文件 pagination.css ul, li { margin: 0px; padding: 0px;} ...
- Vue.js的表格分页组件
转自:http://www.cnblogs.com/Leo_wl/p/5522299.html 有一段时间没更新文章了,主要是因为自己一直在忙着学习新的东西而忘记分享了,实在惭愧. 这不,大半夜发文更 ...
随机推荐
- 泛泰 A850 4.1.2 刷第三方专用Recovery合集
下载 http://download.csdn.net/detail/benjaminwan/7406089 专用于刷基于AOSP4.1.2的乐蛙和MIUIV5 由于本人制作的第三方ROM,为了通刷, ...
- Android五天乐(第三天)ListFragment与ViewPager
1ListFragment 今天首先学习了一种很经常使用的展示场景:列表展示. 昨天学习了使用Fragmet来取代activity进行设计.今天在托管单个fragment的基础上,掌握托管一个布局li ...
- 走进 CPU 的 Cache
看了上一篇文章.你可能非常想知道,为什么程序的执行结果会是这样.如今,就让我们来走进 CPU 的世界. 在 SMP(对称多处理器)时代,多个 CPU 一起工作.使运算能力进一步提升,那么CPU 是怎样 ...
- NHibernate概括
什么是?NHibernate?NHibernate是一个面向.NET环境的对象/关系数据库映射工具. 对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种 ...
- SQLSever: 怎样在select中的每一行产生不同的随机数?
select 的随机函数有点假, 或许是由于它是基于时间来的吧, 同一select中由于时间无法错开导致产生的随机数都是一样的. 怎样做到让不同的行拥有不同的随机数呢? 以下以产生某个月的随机日期来演 ...
- Sql中把datetime转换成字符串(CONVERT)
一.回想一下CONVERT()的语法格式: CONVERT (<data_ type>[ length ], <expression> [, style]) 二.这里注重说明一 ...
- invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
Column 'dbo.tbm_vie_View.ViewID' is invalid in the select list because it is not contained in either ...
- App server 与 Web server之间的区别
原文: http://www.javaworld.com/javaqa/2002-08/01-qa-0823-appvswebserver.html 简单来说,web服务器提供页面给浏览器,而app服 ...
- UVa 11025 The broken pedometer【枚举子集】
题意:给出一个矩阵,这个矩阵由n个数的二进制表示,p表示用p位二进制来表示的一个数 问最少用多少列就能将这n个数区分开 枚举子集,然后统计每一种子集用了多少列,维护一个最小值 b[i]==1代表的是选 ...
- 工作日志:dispatch_once、网络缓存、分享问题
问题描述一: 每一个接口对应的model的数据在进入对应的模块(视图)时,执行一次本地缓存加载: 执行缓存加载的实现在基类实现. 解决方案: 将dispatch_once_t设置为成员变量: 问题扩展 ...