首页 > 其他分享 >Angular 实现分页器组件

Angular 实现分页器组件

时间:2023-09-03 11:44:56浏览次数:27  
标签:totalPage 分页 showEndPage Angular PaginatorComponent maxSize 组件 currentPage page

很感谢 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);
}

 转载请说明注明作者: 书源

标签:totalPage,分页,showEndPage,Angular,PaginatorComponent,maxSize,组件,currentPage,page
From: https://www.cnblogs.com/shuyuanutil/p/17674727.html

相关文章

  • 有关Vue-Cli5.X工程中ESLint组件命名检查问题解决
    个人开发环境简介,工具用的VisualStudioCode,因为每个人的开发环境不同,不可能所有解决方案通用,防止踩坑。PSF:\VueWorkSpace\vue_router_test>node-vv16.12.0PSF:\VueWorkSpace\vue_router_test>npm-v8.1.0PSF:\VueWorkSpace\vue_router_test>npmeslint-v8.1.0......
  • 前端Vue仿企查查天眼查高管信息列表组件
    ​随着技术的不断发展,传统的开发方式使得系统的复杂度越来越高。在传统开发过程中,一个小小的改动或者一个小功能的增加可能会导致整体逻辑的修改,造成牵一发而动全身的情况。为了解决这个问题,我们采用了组件化的开发模式。通过组件化开发,可以有效地实现单独开发,单独维护,而且它们之......
  • 前端Vue仿企查查 天眼查知识产权标准信息列表组件
    ​引入Vue仿企查查天眼查知识产权标准信息列表组件随着技术的不断发展,传统的开发方式使得系统的复杂度越来越高。在传统开发过程中,一个小小的改动或者一个小功能的增加可能会导致整体逻辑的修改,造成牵一发而动全身的情况。为了解决这个问题,我们采用了组件化的开发模式。通过组件......
  • .NET Core如何使用第三方组件Autofac
     首先先了解一下什么是AutofacAutofac用于在.NETCore应用程序中管理组件的生命周期和依赖关系。我们在开发一个项目的时在Program中注入依赖注入的生命周期,项目工程比较大的时候我们就要实现很多注入,最致命的缺点就是耽误太多时间,为解决这一问题的最好解决方法就是使用到......
  • angular - HttpClient
    入门引入HttpClientModule模块//app.module.tsimport{HttpClientModule}from'@angular/common/http';@NgModule({imports:[HttpClientModule],})注入服务实例import{HttpClient}from'@angular/common/http';exportclassAppC......
  • uniapp的u-album组件自定义删除功能
    加是否显示删除按钮图片字段删除按钮删除方法删除按钮样式代码<template><viewclass="u-album"><viewclass="u-album__row"ref="u-album__row"v-for="(arr,index)inshowUrls"......
  • 关于 Angular 应用开发里 Subject 和 BehaviorSubject 的用法一例
    笔者一直在SAP中国研究院从事CommerceCloud这款Angular应用的开发,最近工作中修复了一个bug.在SpartacusUI上点击Create按钮之后:维护User的明细数据,然后点击Save按钮:点击之后,我们期望的结果是收到一条用户成功创建的提示消息,并且页面自动导航回到点击Create......
  • Linux组件安装部署手册模板
    Linux系统-部署-运维系列导航 背景说明组件安装步骤是基本通用的,大部分组件安装都需要经过一些必须的流程,才能成为有效的服务。 本文以Linux(CentOS7)系统为基础介绍,其他操作系统原理一样,只是部分操作的具体执行方式需要根据操作系统调整。  根据经验总结,组件安装一般都......
  • GaoNeng:我是如何为OpenTiny贡献新组件的?
    本文作者:GaoNeng大家好啊,又是我GaoNeng。最近在给OpenTiny做贡献,感觉renderless这个架构还是挺有意思的,就贡献了一个color-picker组件,简单写篇文章稍微记录一下。也欢迎朋友们给TinyVue开源项目点个Star......
  • sbt组件安装(CentOS7)
    Linux系统-部署-运维系列导航 sbt安装支持2种安装方式,yum安装与二进制安装。yum安装scala-sbt官方下载 yum源 #下载yum源[root@localhostkafka-manager]#wgethttps://www.scala-sbt.org/sbt-rpm.repo-O/etc/yum.repos.d/sbt-rpm.repo--2022-02-1518:28:05--......