Skip to content

Latest commit

 

History

History
235 lines (195 loc) · 6.87 KB

File metadata and controls

235 lines (195 loc) · 6.87 KB

Pagination

데이터 묶음으로 가져오기

수많은 데이터가 있을때 묶음으로 가져와 페이지 만들기

URL 쿼리로 page 만들기

  1. views/shop/index.ejs 페이지 추가하기

              <section class="pagination">
                    <a href="/?page=1">1</a>
                    <a href="/?page=2">2</a>
                </section>
  2. public/css/main.css 간단한 페이지 스타일링

    .pagination {
      margin-top: 2rem;
      text-align: center;
    }
    
    .pagination a {
      text-decoration: none;
      color: #00695c;
      padding: 0.5rem;
      border: 1px solid #00695c;
      margin: 0 1rem;
    }
    
    .pagination a:hover,
    .pagination a:active {
      background-color: #00695c;
      color: white;
    }
  3. controllers/shop.js getIndex 에서 query로 페이지 보내주기

    // 페이지당 product 보여줄 갯수 변수로 만들기
    const ITEMS_PER_PAGE = 3;
    
    exports.getIndex = (req, res, next) => {
      // + 는 숫자로 변환 하는 역할
      const page = +req.query.page;
      Product.find()
        // skip을 하면 숫자만큼 결과를 제외하고 보여줌
        // (page-1) * ITMES_PER_PAGE = 이전 페이지 갯수 (그 만큼 제외하고 뒤에 결과 보여줌)   
        .skip((page - 1) * ITEMS_PER_PAGE)
        // 보여줄 갯수 제한
        .limit(ITEMS_PER_PAGE)
        .then(products => {
          res.render('shop/index', {
            prods: products,
            pageTitle: 'Shop',
            path: '/'
          });
        })
        .catch(err => {
          const error = new Error(err);
          error.httpStatusCode = 500;
          return next(error);
        });
    };

페이지 표시하기

페이지 표시 상세하게 구현하기

  1. controllers/shop.js getIndex 에서 render에 전달해줄 페이지 인자 만들기

    exports.getIndex = (req, res, next) => {
        // query 없이 기본 index로 들어가면 처음 페이지로 render
      const page = +req.query.page || 1;
      let totalItems;
    
      Product.find()
        .count.then(numProducts => {
          totalItems = numProducts;
          return Product.find()
            .skip((page - 1) * ITEMS_PER_PAGE)
            .limit(ITEMS_PER_PAGE);
        })
        .then(products => {
          res.render('shop/index', {
            prods: products,
            pageTitle: 'Shop',
            path: '/',
             currentPage: page,
            // 현재페이지 기준으로 다음 페이지 있나?
            hasNextPage: ITEMS_PER_PAGE * page < totalItems,
            // 현재페이지 기준으로 이전 페이지 있나? 1페이지만 아니면 모두 true
            hasPreviousPage: page > 1,
            // 다음페이지 = 현재페이지 + 1
            nextPage: page + 1,
            // 이전페이지 = 현재페이지 - 1
            previousPage: page - 1,
          	// Math.ceil : 주어진 숫자보다 크거나 같은  중 가장 작은 정수
            lastPage: Math.ceil(totalItems / ITEMS_PER_PAGE)
          });
        })
        .catch(err => {
          const error = new Error(err);
          error.httpStatusCode = 500;
          return next(error);
        });
    };
  2. views/shop/index.ejs 페이지 동적으로 바꿔주기

    <%- include('../includes/head.ejs') %>
    <link rel="stylesheet" href="/css/product.css">
    </head>
    
    <body>
        <%- include('../includes/navigation.ejs') %>
    
        <main>
            <% if (prods.length > 0) { %>
            <div class="grid">
                <% for (let product of prods) { %>
                <article class="card product-item">
                    <header class="card__header">
                        <h1 class="product__title"><%= product.title %></h1>
                    </header>
                    <div class="card__image">
                        <img src="/<%= product.imageUrl %>"
                             alt="<%= product.title %>">
                    </div>
                    <div class="card__content">
                        <h2 class="product__price">$<%= product.price %></h2>
                        <p class="product__description"><%= product.description %></p>
                    </div>
                    <div class="card__actions">
                        <a href="/products/<%= product._id %>" class="btn">Details</a>
                        <% if (isAuthenticated) { %>
                        <%- include('../includes/add-to-cart.ejs', {product: product}) %>
                        <% } %>
                    </div>
                </article>
                <% } %>
            </div>
            <section class="pagination">
                <% if (currentPage !== 1 && previousPage !== 1) { %> 
                <a href="/?page=1">1</a>
                <% } %>
                <% if (hasPreviousPage) { %>
                <a href="/?page=<%= previousPage %>"><%= previousPage %></a>
                <% } %>
                <a href="/?page=<%= currentPage %>" class="active"><%= currentPage %></a>
                <% if (hasNextPage) { %>
                <a href="/?page=<%= nextPage %>"><%= nextPage %></a>
                <% } %>
                <% if (lastPage !== currentPage && nextPage !== lastPage) { %>
                <a href="/?page=<%= lastPage %>"><%= lastPage %></a>
                <% } %>
            </section>
            <% } else { %>
            <h1>No Products Found!</h1>
            <% } %>
        </main>
        <%- include('../includes/end.ejs') %>

페이지 다른 메뉴에도 추가하기

  1. views/includes/pagination.ejs

    includes 생성하기

    <section class="pagination">
      <% if (currentPage !== 1 && previousPage !== 1) { %>
      <a href="?page=1">1</a>
      <% } %> <% if (hasPreviousPage) { %>
      <a href="?page=<%= previousPage %>"><%= previousPage %></a>
      <% } %>
      <a href="?page=<%= currentPage %>" class="active"><%= currentPage %></a>
      <% if (hasNextPage) { %>
      <a href="?page=<%= nextPage %>"><%= nextPage %></a>
      <% } %> <% if (lastPage !== currentPage && nextPage !== lastPage) { %>
      <a href="?page=<%= lastPage %>"><%= lastPage %></a>
      <% } %>
    </section>
    
  2. views/shop/index.ejs includes 가져오기

    <%- include('../includes/pagination.ejs', {currentPage: currentPage, nextPage: nextPage, previousPage: previousPage, lastPage: lastPage, hasNextpage: hasNextpage, hasPreviousPage:hasPreviousPage}) %>
  3. 다른페이지에도 추가하기

참고