开发中难免要碰到分页查询的功能实现. 这个功能个人是比较头疼, (1)虽然功能简单, 但实现的严谨还是比较费神的. (2)不能环境下, 一样的分页代码难以满足, 比如html中和jsp中就不一样. 同步请求和异步请求有不一样.
对于一些用于jsp环境的分页套路, 个人不是很喜欢, 没办法, 钟爱前后端分离的套路. 于是想找一款基于js的实现的分页条功能. 无意中发现下面将要介绍的这款插件. 基本功能完全没有问题. 但是想要满足自己的定制化需求还是比较费劲的. 我想这也是前端的通病吧, 变幻莫测. 根本难以一套代码搞定一切场景.
jquery.pagination.js
这一款比较好用前端分页jquery插件.
GitHub地址
demo
image.png
image.png
缺陷
作者的初衷设计是想要样式和功能分离. 这样还是不错的, 留给使用充分的定制空间. 然而, 前端最让我苦恼的就是: (1)定制样式必须要依赖于插件内部生成的html代码. (2)繁琐的样式文件和配置, 还需要手动设置.
在使用这款插件时, 本来想要借助作者提供的样式文件的, 结果一看有四五个, 而且无还不知道怎么配置(没有文档说明), 再加上还要依赖于jquery... 瞬间就失去了兴趣了. 我的要求是, 插件嘛, 一个js, 一个css搞定. 这才叫清爽.
个人觉得bootstrap的分页条比较简洁好看, 但是这款插件不支持.
优化
(1)不想学习配置样式; (2)喜欢bootstrap分页条.
于是, 想起来, 研究下源码吧, 看看能不能优化下, 实现我的需求.
插件有个参数mode: (1)fixed 分页按钮固定, (2)unfixed, 分页按钮不固定.
源码长这样:
image.png
既然这样, 我就想, 不如给你加个mode, 就叫做: bootstrap. 当我如下配置时, 会给出来bootstrap样式的分页条.
配置
bootstrap分页条
优化代码片
增加一个case分支.
case 'bootstrap': // +:引入bootstrap的分页导航条 Nisus 2018-1-31 15:21:51 bug: 目前设置首页和末页后, 下一页有bug, 当前页为1时, 下一页不往下走.
//bootstrap分页的起始
html += '
- ';
if (opts.coping) {
var home = opts.coping && opts.homePage ? opts.homePage : '1';
//首页
// html += '' + home + '';
var startCls = '';
if (current == 1) {
startCls = 'active';
}
html += '
' + home + '';}
//上一页
// html += '
\n' +// ' ' +
// '
';html += '
' + opts.prevContent + '';// ' + opts.prevContent + '
var start = current > opts.count - 1 ? current + opts.count - 1 > pageCount ? current - (opts.count - (pageCount - current)) : current - 2 : 1;
var end = current + opts.count - 1 > pageCount ? pageCount : start + opts.count;
for (; start <= end; start++) {
if (start != current) {
html += '
' + start + '';} else {
html += '
' + start + '';}
}
//下一页
html += '
' + opts.nextContent + '';// html += '
' +// ' ' +
// ' ' + opts.nextContent + '' +
// ' ' +
// '
';if (opts.coping) {
var _end = opts.coping && opts.endPage ? opts.endPage : pageCount;
//末页
var endCls = '';
if(current===pageCount) {
endCls = 'active';
}
html += '
' + _end + '';// html += '' + _end + '';
}
// //尾部
html += '';
break;
应用
页面使用list.jsp, 后台分页使用mybatis的PageHelper插件实现分页查询数据.
流程:
第一次请求list.jsp页面时, 分页数据采用默认值, 后台参数封装类叫做BrandQuery, 该pojo设置分页默认值(当前页1, 页大小9). 服务器响应页面后, 页面数据位加载数据, 分页条处加载分页条. 关键点: 后台需要回传当前页, 让分页插件接收到, 这样才能让当前分页按钮高亮.
之后, 点击分页按钮后, 进入插件中配置的callback(回调函数), 发送表单请求. 请求list.jsp. 实现更新数据.
前端
引入插件
下载插件包. 然后在jsp页面中引入.
jquery.js
jquery.pagination.js
bootstrap的css
数据位接受后台数据
响应的数据, 图省事, 也封装在了BrandQuery类中.
数据位
分页位置代码
//记录当前页
var current = ${brandQuery.current};
current = current === null?1:current;
$('.page-nav').pagination({
mode:'bootstrap', //生成bootstrap风格的分页条
/* ABANDON: 会有bug, 导致'下一页'在当前页为1时失效
coping: true,
homePage: '首页',
endPage: '末页',
*/
prevContent: '上页',
nextContent: '下页',
jump:true,
current:current,
callback:function (api) {
$('#ipt_current').val(api.getCurrent());
$('#queryFormId').submit();
}
})
后台
controller
/**
* 跳转至 ./brand/*
*/
@RequestMapping(value = {"/brand/{page}"})
public String gotoBrandtPage(@PathVariable String page, BrandQuery brandQuery, Model model){
page = "brand/"+page; //不能加 / 了, xml中配置的前缀已经含有 /
log.debug("跳转至:{}", page);
// 查询数据
// 给默认值
// 默认显示出 is_display = 1 i.e. 可见的
if (brandQuery.getIs_display() == null) {
brandQuery.setIs_display(1);
}
// List brands = brandService.queryBrandByNoPage(brandQuery);
brandQuery = brandService.queryBrandByPage(brandQuery);
model.addAttribute("brandQuery", brandQuery);
//查询条件的回显
model.addAttribute("name", brandQuery.getName());
model.addAttribute("is_display", brandQuery.getIs_display());
return page;
}
service
public BrandQuery queryBrandByPage(BrandQuery brandQuery) {
//开启分页查询
PageHelper.startPage(brandQuery.getCurrent(), brandQuery.getShowData());
//仍然借用正常非分页查询的mapper方法
List brands = brandMapper.queryBrandByNoPage(brandQuery);
/*!为了最大限度让用户以前的查询代码丝毫不用变, 改查list就查list!
* 想获取分页信息, 使用包装类即可. 若不嫌麻烦, 也可以修改mapper.xml, 让其返回Page<>对象*/
//获取分页信息
// PageInfo pageInfo = new PageInfo<>(brands);
// int pageCount = pageInfo.getPageNum();
Page page = (Page) brands;
brandQuery.setPage(page);
brandQuery.setCurrent(page.getPageNum());
return brandQuery;
}
效果
分页后效果
不足
存在bug, 增加首页和末页按钮后, 下一页的按钮在当前页为1时失效.
分页条样式有缺陷, 比如效果图中的, 跳转非常难看.
附
PageHelper依赖
我觉的只是个设计精妙的插件. 你可以在原有的dao层代码丝毫不动的情况下, 实现分页功能. 即你不需要为了分页, 而修改mapper接口和mapper.xml. 只需要在查询前, 加上 PageHelper.startPage(...).
com.github.pagehelper
pagehelper
4.1.1