Revel分页需在Controller中创建Paginator实例并传入模板,不可在模板调用New;.Paginator.Pages默认从1开始连续显示,不居中当前页;page参数未传时c.Params.Int返回0,应显式处理为1。

Revel模板里怎么用Paginator对象渲染分页
Revel自带的Paginator不是模板函数,而是控制器传入模板的一个结构体实例,必须先在Controller里构造好再Render进去。常见错误是直接在模板里调Paginator.New()——这行不通,因为New需要*revel.Request和总记录数,模板层拿不到请求上下文。
典型用法:在Controller中计算总条数(比如查一次COUNT(*)),然后创建Paginator,再传给模板:
// controllers/app.go
func (c App) List() revel.Result {
total := countPosts() // 你自己实现的总数查询
paginator := revel.Paginator{Page: c.Params.Int("page"), Per: 10, Total: total}
return c.Render(paginator)
}模板中直接访问Paginator字段即可生成链接和状态:
{{if .Paginator.HasPrev}}
<a href="https://www.php.cn/link/d24188bab970b576a8eee6c41ef1c065">上一页</a>
{{end}}
{{range .Paginator.Pages}}
<a href="https://www.php.cn/link/5da43347b53bce08b4d5f0c181d45dd4">{{.}}</a>
{{end}}
{{if .Paginator.HasNext}}
<a href="https://www.php.cn/link/0672d7ce1aaa6dd7c129f4b1aa87592b">下一页</a>
{{end}}为什么.Paginator.Pages有时只显示1–5,不自动跳转到当前页附近
Revel默认的Pages方法返回的是从1开始的连续页码切片,不会“居中”当前页。比如总页数100、当前页是97,.Paginator.Pages仍返回[1 2 3 4 5],不是[95 96 97 98 99 100]。
立即学习“go语言免费学习笔记(深入)”;
要实现“当前页居中”的分页条,得自己写逻辑或封装辅助函数:
- 在Controller里手动构造一个
[]int范围切片,比如start := max(1, page-2)、end := min(totalPages, page+2) - 把该切片作为新变量传入模板,比如
c.Render(paginator, pageRange) - 避免在模板里做数学运算(Revel模板不支持
+、-等操作符),所有计算必须在Go层完成
分页参数page没传时默认值怎么设
Revel的c.Params.Int("page")在URL无page参数时返回0,而Paginator认为页码从1开始,0会被当作第1页——但这是隐式行为,容易误判。
更稳妥的做法是显式判断并归一化:
page := c.Params.Int("page")
if page < 1 {
page = 1
}
paginator := revel.Paginator{Page: page, Per: 10, Total: total}另外注意:Per字段不能为0,否则Paginator.TotalPages()会panic;Total可以为0,此时TotalPages()返回0,HasPrev/HasNext均为false。
数据库查询怎么配合分页避免全表扫描
Revel本身不处理SQL分页,你得自己拼LIMIT和OFFSET。错误做法是先查全部数据再用slice截取——内存和性能双爆炸。
正确姿势是把page和per转成OFFSET和LIMIT传给ORM或原生SQL:
-
offset := (page - 1) * per(注意不是page * per) - 使用
OFFSET offset LIMIT per查当前页数据 - 总数查询必须独立执行(
SELECT COUNT(*) FROM ... WHERE ...),不能复用带LIMIT的语句 - 如果表很大且
OFFSET值极高(比如第10万页),考虑改用游标分页(基于ID或时间戳),否则MySQL会扫过前999990行
游标分页没法用Paginator的页码逻辑,得自己设计next_cursor和prev_cursor参数,这时候Paginator就该弃用了。


















