設置商品頁數

mongoose skip() ⇒ 跳過幾條

mongoose limit() ⇒ 指定返回幾筆檔案

截圖 2021-09-01 下午5.37.47.png

截圖 2021-09-01 下午5.39.36.png

計算分頁總數

countDocuments() ⇒ 查找總數

// 查詢商品總數

Product.find().countDocuments().then(numProd => {
	// numProd 商品總數
})
// controllers/shop.js
exports.getProducts = (req, res, next) => {
  const ITEMS_PER_PAGE = 6;
  let totalItems = 0;
  // page當前頁數
  const page = +req.query.page || 1;
  console.log(page);
  Product.find()
    .countDocuments()
    .then((numProducts) => {
      totalItems = numProducts;
      // 商品總數/每頁顯示量 => 總頁數
      totalPage = Math.ceil(totalItems / ITEMS_PER_PAGE);
      return Product.find()
        .skip((page - 1) * ITEMS_PER_PAGE)
        .limit(ITEMS_PER_PAGE);
    })
    .then((products) => {
      res.render("shop/product-list", {
        prods: products,
        docTitle: "产品中心",
        activeProductList: true,
        breadcrumb: [
          { name: "首页", url: "/", hasBreadcrumbUrl: true },
          { name: "产品中心", hasBreadcrumbUrl: false },
        ],
        totalItems,
        totalPage,
        hasNextPage: ITEMS_PER_PAGE * page < totalItems,
        hasPrePage: page > 1,
        nextPage: page + 1,
        prevPage: page - 1,
        firstPage: 1,
        currentPage: page,
      });
    })
    .catch((err) => {
      const error = new Error(`取得商品頁err: ${err}`);
      error.httpStatuCode = 500;
      return next(error);
    });
};

在ejs對分頁盼對做設定

// product-list.js
<nav aria-label="Page navigation example">
    <ul class="pagination">

        <% if(!hasPrePage) { %>
            <li class="page-item disabled">
                <div class="page-link">
                    <span aria-hidden="true">&laquo;</span>
                </div>
            </li>
        <% } else { %>
            <li class="page-item">
                <a class="page-link" href="?page=<%= prevPage %>" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                </a>
            </li>
        <% } %>
        <% for (let numPage = 0; numPage < totalPage; numPage++) { %>
            <% if (currentPage === numPage + 1) { %>
                <li class="page-item active">
                    <a class="page-link" href="?page=<%= numPage + 1%>"><%= numPage + 1 %></a>
                </li>
            <% } else { %>
                <li class="page-item">
                    <a class="page-link" href="?page=<%= numPage + 1%>"><%= numPage + 1 %></a>
                </li>
            <% } %>
        <% } %>
        <% if(!hasNextPage) { %>
            <li class="page-item disabled">
                <div class="page-link">
                    <span aria-hidden="true">&raquo;</span>
                </div>
            </li>
        <% } else { %>
            <li class="page-item">
                <a class="page-link" href="?page=<%= nextPage %>" aria-label="Next">
                    <span aria-hidden="true">&raquo;</span>
                </a>
            </li>
        <% }  %>
    </ul>
</nav>

mongoose-paginate

$ npm i mongoose-paginate-v2 -d

引入

// 再要使用的model引入
// models/products.js
const mongoose = require("mongoose");
const mongoosePaginate = require("mongoose-paginate-v2");

const productSchema = new mongoose.Schema(
  {
    title: { type: String, required: true },
    imageUrl: { type: String, required: true },
    price: { type: Number, required: true },
    description: { type: String, required: true },
    userId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
  },
  { versionKey: false }
);

productSchema.plugin(mongoosePaginate);

module.exports = mongoose.model("Product", productSchema);

截圖 2021-09-06 上午11.12.56.png

pagation().then() 會回傳Product全部資料及分頁資訊

截圖 2021-09-06 上午11.14.10.png