67.模板详细使用(三) 一个简单的分页

分页是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>&nbsp;&nbsp;
<a href="?page={{.pageData.prepage}}">上页</a>&nbsp;&nbsp;
<a href="?page={{.pageData.nextpage}}">下页</a>&nbsp;&nbsp;
<a href="?page={{.pageData.lastpage}}">末页</a>&nbsp;&nbsp;
当前页:{{.pageData.currentpage}}

</body>
</html>
{{end}}

很简单的模板,只为了说明问题。
运行效果如下图


首页
末页

当你在末页的情况下,还点击下页的时候,会跳转到第1页。
在首页的情况下,还点击上页的时候,页面会留在首页。
这个例子已经能在大多数情况下使用了。

推荐阅读更多精彩内容

  • pdf下载地址:Java面试宝典 第一章内容介绍 20 第二章JavaSE基础 21 一、Java面向对象 21 ...
    王震阳阅读 79,434评论 26 513
  • 今天看到一篇関于中醫的訪談,里面提到的中醫理念很精致,很漂亮,但是精致、漂亮到令人憂傷。太理想了,反而容易失敗 甚...
    王玨新派中醫阅读 127评论 1 0
  • 《金粉世家》里清秋是个外冷内热的妙人,她有气韵,有风骨,但气韵和风骨似乎是在曾经沧海后养成的,这样一个人如其名,清...
    墨上秋阅读 49评论 0 0
  • 今天早上儿子睡了一个小小的懒觉,按照学习计划,起来吃完饭后便陪他开始学习,利用早上的时间让他背背古诗、背背...
    花知花落阅读 33评论 0 0
  • 小朱昨晚焦虑地打电话找我教练。 原来她要去面试一家世界500强的企业,心里有压力。 在打电话的过程中,她鼻音很重,...
    光年313阅读 24评论 0 0