「分頁」的功能邏輯其實就是一串數字算式:
- 假設每頁限制放 10 筆資料:pageLimit = 10
- 開始計算新的一頁時,偏移 offset = (page — 1) * limit
- 使用 Sequlize 查詢資料時,可以直接指定 offset 和 limit,他就會幫你取出需要的資料
關於導覽器,實作概念是直接傳一個陣列如:[1, 2, 3, 4, 5, 6],這樣就可以直接用 Handlebars 的 each-helper 做出
因此就有了這兩行程式碼:
const pages = Math.ceil(result.count/pageLimit)const totalPage = Array.from({length: pages}).map((item, index) => index+1)
pages 是頁數的最大值。在用 findAndCountAll 來撈資料以後,可以用 result.count 知道總共有幾筆餐廳,除以每頁筆數後,用 Math.ceil 無條件進位之後就是最大頁數。
接著運用 Array.from({length: pages}) 做出長度符合的陣列,然後再用 map 把真正的數字帶進去,+1因原陣列開頭為0
上一頁與下一頁
在分頁導覽器上有「上一頁 (prev)」和「下一頁 (next)」的按鈕,只需要根據目前的頁面加減一,要記得考慮到最大值和最小值,因此要加入條件式,像這樣:
let prev = page-1 < 1 ? 1 : page-1
let next = page+1 > pages ? pages : page+1
實作 View
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="/restaurants?page={{prev}}&categoryId={{categoryId}}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{{#each totalPage}}
{{#ifCond this ../page}}
<li class="page-item active"><a class="page-link" href="#">{{this}}</a></li>
{{else}}
<li class="page-item"><a class="page-link"
href="/restaurants?page={{this}}&categoryId={{../categoryId}}">{{this}}</a></li>
{{/ifCond}}
{{/each}}
<li class="page-item"><a class="page-link" href="/restaurants?page={{next}}&categoryId={{categoryId}}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>