就先來看看使用Laravel提供Pagination能夠多麼簡單。
首先,控制器只需要使用BlogPost::paginate($limit)
查詢就好,並將查詢結果直接傳遞給視圖。
public function index()
{
// 如果想要將每頁顯示數量變成可以調整的,
// index需要傳入 (Request $request),並由下方方式取得$limit傳入paginate
// $limit = $request->query('limit', 30);
$posts = BlogPost::paginate(30);
return view("blog/index",[
"posts"=>$posts,
]);
}
BlogPost::paginate($limit)
會自動根據Request的page
參數取得存取的頁面,自動計算offset
,並根據給予的每頁顯示數量限制來查詢。甚至連index()
都不需要傳入Request $request
。傳給視圖的也少了不少。說到視圖,立馬來看看變得多簡潔:
@section('body')
<div class="container">
<ul>
@foreach ($posts as $post)
<li>
<a href="{{route('blog/post.show',['id'=>$post->id])}}">{{ $post->title }}</a>
</li>
@endforeach
</ul>
</div>
{{-----------------------------------}}
{{ $posts->links() }}
@endsection
列出文章清單的部份,大致什麼太大變化。但是頁面頁數選項不再那麼複雜,沒錯,只需要$post->links()
就好。他會自動生成符合Bootstrap的Pagination。在瀏覽器接受到的HTML樣子可能如下:
呵呵,根本不需要寫這麼麻煩...也太簡單了吧!
<ul class="pagination" role="navigation">
<li class="page-item">
<a class="page-link" href="http://localhost/blog/post?page=1" rel="prev" aria-label="« Previous">‹</a>
</li>
<li class="page-item"><a class="page-link" href="http://localhost/blog/post?page=1">1</a></li>
<li class="page-item active" aria-current="page"><span class="page-link">2</span></li>
<li class="page-item disabled" aria-disabled="true" aria-label="Next »">
<span class="page-link" aria-hidden="true">›</span>
</li>
</ul>
你可以回去昨天文章看看,差了多少(上個版本根據Bootstrap的Pagination去寫blade模板,現在自動生成)。更有意思的是,$posts->links()
會自動判斷是否需要生成頁面頁數選項。當資料量總數低於限制數時(上例為30),完全不會產生頁面選項。不像之前如果僅有一頁,還是照樣顯示、顯示下一頁
、上一頁
。
所以要看到效果,你可能還要填入更多的假文章,填充進資料庫模擬。
最後,來簡單加入新增文章的連結,以及刪除文章的功能按鈕,完整程式如下:
@extends("base",['title'=>'網誌文章'])
@section('title', '網誌文章')
@section('body')
<div class="container">
<a href="{{route('blog/post.create')}}"><input class="btn btn-primary" name="" type="button" value="新增文章"/></a>
<ul>
@foreach ($posts as $post)
<li>
<a href="{{route('blog/post.show',['id'=>$post->id])}}">{{ $post->title }}</a>
<form class="form-inline"
action="{{route('blog/post.destroy',['id'=>$post->id])}}"
method="post">
@csrf
@method('delete')
<input class="btn btn-danger" name="" type="submit" value="刪除"/>
</form>
</li>
@endforeach
</ul>
</div>
{{ $posts->links() }}
@endsection
刪除按鈕看起來有點丑...應該大可以寫成component,或是使用js榜定、Ajax的方式。
最後來看看Pagination還提供什麼用法:
// 當前取得數量
$results->count()
// 判斷是否有足夠的項目用於分頁
$results->hasMorePages()
// 每頁顯示的項目數量
$results->perPage()
// 目前結果中,第一個項目編號
$results->firstItem()
// 目前結果中,最後一個項目編號
$results->lastItem()
// 當前頁碼
$results->currentPage()
// 最後一頁頁碼
$results->lastPage() //(Not available when using simplePaginate)
// 下一頁連結
$results->nextPageUrl()
// 前一頁連結
$results->previousPageUrl()
// 是否為第一頁
$results->onFirstPage()
// 項目總數
$results->total() //(Not available when using simplePaginate)
// 特定URL
$results->url($page)
所以可以自訂出其他樣式,像是簡單點的例子:{{$results->count()}} / {{$results->total()}}
。
上面我好像抄到5.6版本,5.8有更多使用方式。