做WEB应用不可避免的要对查找到的数据进行分页的处理。
做分页的目的不是简单的为了界面的美观,也是为了防止一次查找到过多的数据占用服务器内存。分页其实就是限制查找的SQL语句一次只能查找到一页的数据量,然后以分页的形式展示出来。
所以简单总结下分页的好处:
官方文档中给到:
ThinkPHP5.0 内置了分页实现,要给数据添加分页输出功能在 5.0 变得非常简单,可以直接在 Db 类 查询的时候调用 paginate 方法:
// 查询状态为1的用户数据 并且每页显示10条数据
$list = Db::name('user')->where('status',1)->paginate(10);
// 把分页数据赋值给模板变量
list $this->assign('list', $list);
// 渲染模板输出
return $this->fetch()
也可以改成模型的分页查询代码:
// 查询状态为1的用户数据 并且每页显示10条数据
$list = User::where('status',1)->paginate(10);
// 把分页数据赋值给模板变量
list $this->assign('list', $list);
// 渲染模板输出
return $this->fetch()
模板文件中分页输出代码如下:
<div>
<ul>
{volist name='list' id='user'}
<li> {$user.nickname}li>
{/volist}
ul>
div>
{$list->render()}
参数 | 描述 |
---|---|
list_rows | 每页数量 |
page | 当前页 |
path url | 路径 |
query url | 额外参数 |
fragment url | 锚点 |
var_page | 分页变量 |
type | 分页类名 |
可以在调用分页方法的时候传入,例如:
$list=Db::name('user')->where('status',1)->paginate(10,true,[
'type'=>'bootstrap',
'var_page'=>'page', ]);
划重点了,专业采坑,造福后人。
为了考虑到用户体验:我们一定会考虑到在某个分页页面进行操作后再回到该页面!而不是方法默认的第一页面。
如图:
当我在第二页点击报名后,进入后台操作时,渲染回第二页,而不是到第一页。
当时我想到的解决方法主要有三个:
方法1. 直接不进入后台采用Ajax的方法进行传参,然后局部刷新界面;
方法2.采用cookie或者session存储prevurl(执行跳转之前的路径),操作成功后跳转到pervurl;
方法3.采用paginate()方法的page参数。
方法一比较简单,我之前的博客也写到过Ajax实现二级联动只不过是后台操作变为报名操作,然后success后将界面通过jQuery的html()方法改变就行了。
方法二我是在一个TP3的项目中找到的,在TP5中有些方法已经被遗弃。
$p = I("get.page") ? I("get.page") : 1;
cookie("prevUrl", "Admin/Order/order/page/" . $p);
解释:
通过I方法看是否get得到page参数(TP5中为input()方法),如果get不到意味第一次进入分页界面,否则获取到当前分页,并且将$page以参数的形式拼好路由存入cookie。
$this->success("操作成功", cookie("prevUrl"));
解释:
即为后退一步。
方法三为TP5框架自带的方法,提倡使用。主要是配置paginate()方法的page参数。这里的page参数的意义为渲染的时候从第几页开始读起。
主要问题是:你在分页页面的模板渲染函数中采用GET方法获取page参数,然后将参数以变量的方式传给page参数。
我们理一下思路,GET方法是通过url传参的,
public/index/join_controller/jointeam.html?page=2
当我们点击第二分页的时候,url类似于这种形式,所以我们才能GET到,
当我们执行操作的的逻辑为: 第二分页的界面 -> 后台的报名操作 -> 模板渲染函数 -> 界面
所以在模板渲染函数中的GET方法是获取不到page的,因为它的上一步操作的url为报名操作,而不是page为2的界面。
所以:只有界面到模板渲染函数的才能GET到page,既点击这东西才行获取到。
怎么解决?
则在模板渲染的时候添加这个逻辑:
if(isset($_GET['page'])){
$page = $_GET['page'];
Cookie::set('pageTeam',$page,['prefix'=>'page_','expire'=>3600]);
}
elseif (Cookie::get('pageTeam','page_')!=null){
$page=Cookie::get('pageTeam','page_');
}
else{
$page = 1;
}
解释:
当是界面到模板渲染函数的时候(既点击跳转分页的时候)我们将page存入cookie;
如果GET获取不到,即为后台的报名操作 -> 模板渲染函数 -> 界面(点了报名操作)
所以就将cookie中的值赋给page,得到当前页。
然后再配置paginate()方法的page参数:
paginate(10, false,['page'=>$page]);
代码总览:
这个是我直接从项目中复制的,不太完整,但分页处理已经都在里面了。
public function joinTeam()
{
if(isset($_GET['page'])){
$page = $_GET['page'];
Cookie::set('pageTeam',$page,['prefix'=>'page_','expire'=>3600]);
}
elseif (Cookie::get('pageTeam','page_')!=null){
$page=Cookie::get('pageTeam','page_');
}
else{
$page = 1;
}
$this->setingTimeInfo();
//获取到登陆用户的权限信息
$role=Session::get('ROLE','think');
if($role==TEACHER_RULE) {//如果是院系管理员权限,只能获取到本院的报名信息
$teamUnit = Unit::where('CATEGORY', CATEGORY::team)->paginate(5, false,['page'=>$page]);
$deptId = Session::get('DEPTID', 'think');//获取登陆用户的院系信息
$teamUnit=$this->getJoinTeamState($teamUnit,$deptId);//为团队项目赋当前报名状态值
$this->assign('teamUnit',$teamUnit);
return $this->fetch();
}
1.如果考虑到cookie的浏览器适配的原因可以采用seesion;
2.最后记得将cookie或者session清理掉。