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> <a href="?page={{.pageData.prepage}}">上頁</a> <a href="?page={{.pageData.nextpage}}">下頁</a> <a href="?page={{.pageData.lastpage}}">末頁</a> 當前頁:{{.pageData.currentpage}} </body> </html> {{end}}
很簡單的模板,只為了說明問題。
執行效果如下圖

首頁

末頁
當你在末頁的情況下,還點選下頁的時候,會跳轉到第1頁。
在首頁的情況下,還點選上頁的時候,頁面會留在首頁。
這個例子已經能在大多數情況下使用了。