分页是web页面中常见的功能实现。下面来用一个简单的例子说明一个实现的方法。
首先这只是一个例子,所以就不用从数据库里读取数据那么麻烦了。声明一个切片,把全部数据都放这里,用来代替数据库里的全部数据了。
//全部数据var dataAll = []string{}
也没时间去搜罗数据,就自动生成好了。为了省事,就用unicode编码随机汉字了。(这样会出现很多生僻字哦)
//自动生成全部数据 if len(dataAll)<20 { for i := 0; i < 99; i++ { aString := "" rand.Seed(time.Now().UnixNano()) aNum := rand.Intn(5)+5 for j:=0; j<aNum; j++{ rand.Seed(time.Now().UnixNano()) time.Sleep(time.Nanosecond) aString += string(19968+rand.Int63n(40869-19968)) } dataAll = append(dataAll, strconv.Itoa(i+1)+"、"+aString) } }
还需要有存放当前显示数据的地方、当前的页码、每页显示的记录数
//当前显示数据 var dataNow = []string{} //当前页码 var pageNum = 0 //每页显示记录数 var recordPerPage = 5
我就设置成每页都显示 5 条记录吧。实际情况,可以随时修改,或者从传递来的参数中获取。
当前页码一定是传递来的参数,因为要分页,所以一定是传递来的。我这里就用显式的获取方式。
//获取当前页码 pageNum,err := strconv.Atoi(request.FormValue("page")) if err != nil{ pageNum = 0 }
如果获取出现错误,就把当前页设置为第一页 pageNum = 0
获取当前显示的数据略有些小技巧。你需要处理如果当前页码超出了总页码范围的情况。我这里都把页面跳转为第一页。
//获取当前显示数据 if pageNum * recordPerPage >= len(dataAll) || pageNum * recordPerPage < 0{ pageNum = 0 } for i := 0; i < recordPerPage && (pageNum * recordPerPage + i)< len(dataAll); i++ { dataNow = append(dataNow, dataAll[pageNum * recordPerPage + i]) }
这时候,已经获取到界面显示的主要内容了,就是 dataNow。不过,还需要分页控制啊,所以还要建立分页数据。首页、上页、下页、末页
//分页数据 var firstPage = 0 var lastPage = len(dataAll)/recordPerPage if lastPage*recordPerPage < len(dataAll) { lastPage++ } var nextPage = pageNum + 1 var prePage = pageNum - 1
不用担心 nextPage 和 prePage 超出范围,因为前面的代码已经处理过超出后的情况了。
下面为了把记录和分页数据都传递到页面上,先把分页数据组合成一个映射
var page4 = map[string]int{"firstpage":firstPage,"lastpage":lastPage-1,"nextpage":nextPage, "prepage":prePage, "currentpage":pageNum+1}
当然为了也能够表现当前页,还增加了一个 currentpage。
之后当然是把全部要传递到页面的数据都组织起来。因为数据结构比较复杂,这里需要 interface 类型来担当数据类型。
var dataReturn = map[string]interface{}{"listData":dataNow,"pageData":page4}
好了,模板页面就是要绑定 dataReturn 了。
t, _ := template.ParseFiles("./JoelTemplate/sayHelloTurnPage.html") t.ExecuteTemplate(writer, "page", dataReturn)
我的模板是 sayHelloTurnPage.html
看一下完整代码吧
//全部数据var dataAll = []string{} func Joeltemplate10(writer http.ResponseWriter, request *http.Request) { //当前显示数据 var dataNow = []string{} //当前页码 var pageNum = 0 //每页显示记录数 var recordPerPage = 5 //自动生成全部数据 if len(dataAll)<20 { for i := 0; i < 99; i++ { aString := "" rand.Seed(time.Now().UnixNano()) aNum := rand.Intn(5)+5 for j:=0; j<aNum; j++{ rand.Seed(time.Now().UnixNano()) time.Sleep(time.Nanosecond) //电脑运算太快了,短暂休眠避免随机汉字重复 aString += string(19968+rand.Int63n(40869-19968)) } dataAll = append(dataAll, strconv.Itoa(i+1)+"、"+aString) } } //获取当前页码 pageNum,err := strconv.Atoi(request.FormValue("page")) if err != nil{ pageNum = 0 } //获取当前显示数据 if pageNum * recordPerPage >= len(dataAll) || pageNum * recordPerPage < 0{ pageNum = 0 } for i := 0; i < recordPerPage && (pageNum * recordPerPage + i)< len(dataAll); i++ { dataNow = append(dataNow, dataAll[pageNum * recordPerPage + i]) } //分页数据 var firstPage = 0 var lastPage = len(dataAll)/recordPerPage if lastPage*recordPerPage < len(dataAll) { lastPage++ } var nextPage = pageNum + 1 var prePage = pageNum - 1 var page4 = map[string]int{"firstpage":firstPage,"lastpage":lastPage-1,"nextpage":nextPage, "prepage":prePage, "currentpage":pageNum+1} var dataReturn = map[string]interface{}{"listData":dataNow,"pageData":page4} t, _ := template.ParseFiles("./JoelTemplate/sayHelloTurnPage.html") t.ExecuteTemplate(writer, "page", dataReturn) }
然后在 main 函数中
http.HandleFunc("/page/", JoelTempFunc.Joeltemplate10) server := http.Server{Addr:":8090"} server.ListenAndServe()
我的模板是这样的
{{define "page"}}<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Go Web Programming</title></head><body>分页啦<hr>{{range .listData}} {{.}}<br>{{end}}<a href="?page={{.pageData.firstpage}}">首页</a> <a href="?page={{.pageData.prepage}}">上页</a> <a href="?page={{.pageData.nextpage}}">下页</a> <a href="?page={{.pageData.lastpage}}">末页</a> 当前页:{{.pageData.currentpage}}</body></html>{{end}}
很简单的模板,只为了说明问题。
运行效果如下图
首页
末页
作者:厚土火烟
链接:https://www.jianshu.com/p/a17bd327ba4a