美文网首页GolangGoGolang语言社区
67.模板详细使用(三) 一个简单的分页

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

作者: 厚土火焱 | 来源:发表于2018-09-14 00:28 被阅读44次

    分页是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页。
    在首页的情况下,还点击上页的时候,页面会留在首页。
    这个例子已经能在大多数情况下使用了。

    相关文章

      网友评论

        本文标题:67.模板详细使用(三) 一个简单的分页

        本文链接:https://www.haomeiwen.com/subject/uzpwgftx.html