前言:
做WEB應用不可避免的要對查找到的數據進行分頁的處理。
做分頁的目的不是簡單的爲了界面的美觀,也是爲了防止一次查找到過多的數據佔用服務器內存。分頁其實就是限制查找的SQL語句一次只能查找到一頁的數據量,然後以分頁的形式展示出來。
所以簡單總結下分頁的好處:
- 用戶體驗
- 加載時間和服務器負載
- 提升瀏覽量和廣告收入
TP5框架下的分頁:
官方文檔中給到:
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參數。
方法1:
方法一比較簡單,我之前的博客也寫到過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清理掉。