说明
在开发中分页功能几乎是必不可少的一项功能,使用beego框架开发时,就遇到了分页功能的需求。可能是之前版本并不支持,我发现有很多自己实现的分页功能的封装,在阅读了官方源码时,我发现了分页功能的封装,但是我觉得使用起来非常难用,后来在官方文档里发现,其给的示例中使用了前端的框架,把分页交给前端是个明智的选择。
以下为官方的示例:链接
type Page struct {PageNo intPageSize intTotalPage intTotalCount intFirstPage boolLastPage boolList interface{}
}
func PageUtil(count int, pageNo int, pageSize int, list interface{}) Page {tp := count / pageSizeif count % pageSize > 0 {tp = count / pageSize + 1}return Page{PageNo: pageNo, PageSize: pageSize, TotalPage: tp, TotalCount: count, FirstPage: pageNo == 1, LastPage: pageNo == tp, List: list}
}
可以看到,官方只是实现了根据总数和每页个数计算页数逻辑,那么更重要的,是在前端。
<script type="text/javascript" src="/static/js/bootstrap-paginator.min.js"></script>
<script type="text/javascript">$(function () {$("#page").bootstrapPaginator({currentPage: '{{.Page.PageNo}}',totalPages: '{{.Page.TotalPage}}',bootstrapMajorVersion: 3,size: "small",onPageClicked: function(e,originalEvent,type,page){window.location.href = "/?p=" + page}});});
</script>
前端也只是写了配置,对于刚上手的人来说,好像一头雾水。
思路
既然是前端作为主要实现,那么解决方案分为两种:
1. 把所有数据都传到前端,在前端实现对不同页数据的分割,这适用于数据量较小的情况。
2. 把一部分数据传到前端,只传需要分页的那一部分。这适用于大量的数据。
我这里讲的是后者的实现。
前端
根据github地址,找到相关项目,但其官网已经打不开了,只能去下载release版本:https://github.com/lyonlai/bootstrap-paginator/releases
解压后会有index.html的官方文档,里面讲了一些简单的用法,具体的配置也可以看这个:http://www.cnblogs.com/moretry/p/4441728.html
<link href="css/bootstrap.css" rel="stylesheet">
<script type="text/javascript" src="js/jquery-1.8.1.js"></script>
<script type="text/javascript" src="js/bootstrap-paginator.min.js"></script>
需要引入相关文件,其中依赖bootstarp和jQuery>=1.8,在bootstarp2.x里必须用<div>
标签来使用,在bootstarp3.x里必须使用<ul>
标签来使用。
以下是我的写法,因为其将marginTop设置为20px,我不需要,所以又调了。
<script type="text/javascript">$(".page").bootstrapPaginator({currentPage: '{{.Page.PageNo}}',totalPages: '{{.Page.TotalPage}}',useBootstrapTooltip:'true',bootstrapMajorVersion: 3,size: "small",onPageClicked: function (e, originalEvent, type, page) {window.location.href = "/problems?p=" + page}});$(".pagination").css('margin',0)
</script>
在后端,我添加了对不合法页数的修正,同时又将返回的数据设置成了slice,当然在控制器传参时会出现一些问题,可以参考我前一篇文章的解决方案:链接
func PageUtil(count int, pageNo int, pageSize int, list []interface{}) Page {tp := count / pageSizeif count % pageSize > 0 {tp = count / pageSize + 1}if pageNo < 1 || pageNo * pageSize >= count+pageSize{pageNo = 1}st,end := pageSize*(pageNo-1),pageSize*(pageNo)if st > count || st < 0{st = 0;}if end >count || end < 0 {end = count}pageList := list[st:end]
return Page{PageNo: pageNo, PageSize: pageSize, TotalPage: tp, TotalCount: count, FirstPage: pageNo == 1, LastPage: pageNo == tp, List: pageList}
}
还有一种设计,是设计后端api,然后前端去ajax,但是我觉得没有这种实现更简单,有兴趣的可以去研究研究。