티스토리 뷰

Node.js

게시판 pagination

LHOIKTN 2021. 5. 3. 01:02

원래 뭐라도 코드를 적어가면서 생각하곤 했는데 게시판 만들기 코드는 괜히 잘못 건드리면 에러 찾다가 끝날 것 같아서 미리 어떻게 할지 생각을 해보기로 했다.

 

페이지네이션 알고리듬.txt
0.00MB

이렇게 생각을 미리 하고 하니까 잠깐씩 막히는 부분은 있었지만 쉽게 구현할 수 있었다.  깨끗하지는 않지만 뭐 일단 기능을 구현했다는 점에서 만족스럽다. ((위 텍스트 파일은 생각나는 대로 써서 좀 엉망이다;))

js

더보기
const articleCount=15;//표현될 글의 수 
const pageCount = 10; //페이지 블록 하나에 들어가는 페이지 수 


router.get('/list', (req, res) => {
    let sql = `select idx,subject,id,content,hit,date_format(today,'%Y-%m-%d')as today,number from gesipan order by idx desc `;
    let page=req.query.page;
    //최초시작할 때. page=1로 받을 수 있도록 관련된 html을 수정해야함. 
    // 뷰에서 리스트로 갈 때, 삭제할때, 
    if(page==undefined) page=1; //일단 이렇게 막아놓자.
    connection.query(sql, (error, results) => {
        if (error) {
            console.log(error);
        } else {
//===========글 삭제를 고려하여  글 번호를 바꾸는 부분.             
            let total_record = results.length;
            results.forEach(ele => {
                ele.number = total_record--;
            });
//==========pagination start============
            let article = results.length; // 글 갯수를 받는 변수 
            // const articleCount = 10; //제일 위에 const로 설정. 
            let arr = [[]];  //arr는 이차원 배열.(1행에는 1부터 10까지 2행에는 11부터 20까지.)
            let i = 0;  //2차원배열을 사용한 이유는 for in문을 활용하기 위함. for in문은 배열을 반복해서 범위를 정해주려면 range를 써야함. 
            let j = 1; //range를 이용하면 1차원 배열로 가능???
            //이중 배열을 만들기 위한 반복문. (( 더 좋은 아이디어 찾기))    
            while (article > 0) {
                if (j > pageCount) {
                    j = 1;
                    i++;
                    arr[i] = [];
                }
                arr[i].push(i * pageCount + j);
                article -= articleCount;
                j++;
            }

            let last = i * pageCount + j-1; //끝 버튼 눌럿을 때 사용. 마지막 페이지를 의미  
            let prev = Number(page); //이전 버튼 눌렀을 때 사용. page의 type이 String이라 바꿔줘야함.  
                do{
                    prev--
                }while(prev%pageCount!=0); 

            let next =Number(page);  //다음버튼 눌럿을 떄 사용. 
                do{
                    next++
                }while(next%pageCount!=1);

            let pagiBlock=Math.floor((page-1)/pageCount);//배열에서 원하는 행을 불러오기 위해 만든 변수
            let selectedResult=[]; //results에서 페이지 조건에 맞는 글만 추출하여 담는 배열. 
            // 페이지 조건에 맞는 글만 추출하는 반복문.. 일단 만들기는 했는데 
            // where절에 조건문 주고 거기에 limit하면 될듯. 
            //sql 실행하는 함수가 빠를까 for문 끝까지 돌리는 게 빠를까. 
            for(let i=0; i<results.length; i++){
                if(results[i].number<=results.length-(page-1)*articleCount){
                    selectedResult.push(results[i]); 
                }
                if(selectedResult.length==articleCount) break; 
            }
            
//==========pagination end============
//list로 연결된거도 다 바꿔줘야함.
            res.render('./board/list.html', {
                list: selectedResult,
                pagiBlock:pagiBlock,
                page:page,
                arr:arr,
                last:last,
                prev:prev,
                next:next,  
            });
        }
    });
});

 

 

html

더보기
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="/css/index.css">
</head>
<body>
  {% include "../layout/top.html" %}
  <div id="wrap">
    <div class="container1200">
      
      <table>
              <th>번호</th>
              <th>제목</th>
              <th>작성자</th>
              <th>날짜</th>
              <th>조회수</th>
          {% for item in list %}
          <tr id='tableList'>
              <td>{{item.number}}</td>
              <td><a href="/board/view?idx={{item.idx}}">{{item.subject}}</a></td>
              <td>{{item.id}}</td>
              <td>{{item.today}}</td>
              <td>{{item.hit}}</td>
          </tr>
          {% endfor %}

      </table>
      <div class="btnBox">
        <a href="/board/write" class="boardBtn">글쓰기</a>
      </div>
      <div id="pagenation">

        {% if pagiBlock!=0 %}
        <a href="/board/list?page=1" class='pagination'>처음</a>
        <a href="/board/list?page={{prev}}" class='pagination'>이전</a>
        {% endif %}

        {% for ele in arr[pagiBlock] %}
          {% if ele==page %}
            <a href="/board/list?page={{ele}}" class='pagination nowPage'>{{ele}}</a>
          {% else %}
            <a href="/board/list?page={{ele}}" class='pagination'>{{ele}}</a>
          {% endif %}
        {% endfor %}

        {% if pagiBlock!=arr.length-1 %}
        <a href="/board/list?page={{next}}" class='pagination'>다음</a>
        <a href="/board/list?page={{last}}" class='pagination'>끝</a>
        {% endif %}

      </div>

      {% include "../layout/right.html" %}  
      {% include "../layout/left.html" %}  
    </div>
  </div>
</body>
</html>

 

 

우선 기능을 파악하기로 했다.  

한 페이지에 나오는 글의 수가 정해져 있고, 그게 페이지로 구분된다.  

페이지 넘버는 양의 정수

 

[처음]을 누르면 1페이지로 이동하고, [끝]을 누르면 마지막 페이지로 이동한다. 

[이전]을 누르면 이전 페이지 블록의 마지막 페이지로 이동한다. 

[다음]을 누르면 다음 페이지 블록의 첫번째 페이지로 이동한다. 

 

여기서 페이지 블록이란 한번에 표출되는 페이지의 수를 의미한다. 

 

위의 영상에서 첫번쨰 페이지 블록에는 페이지 1부터 10까지 들어있고, 

두 번째 페이지 블록에는 페이지 11부터 20까지 들어있다. 

 

첫번째첫 번째 페이지 블록일 때, 다음을 누르면 다음 페이지 블록의 첫 번째 페이지인 11로 이동해야 한다. ( 보통의 게시판은 이렇게 작동한다. 디씨인사이드는 좀 다르다. 예를 들어.. 7을 누르면 17로 이동한다. ) 

 

첫 번째 페이지 블록에는 처음과 이전이 없고, 마지막 페이지 블록에는 다음과 끝이 없다. 

 

글을 페이지로 나눠서 담고,  어떤 페이지를 누르면 그 부분에 해당하는 글들을 for문을 통해 뿌려주면 된다.

 

그런데 nunjucks에서 그동안 흔히 사용하던 for(;;) 구문이 아니라 for in문을 통해 반복문을 처리해서 배열을 사용해서 자료구조를 만들기로 했다.  range()를 쓰면 된다고도 하는데.. range는 좀 익숙하지가 않아서 배열을 만드는 게 더 쉬울 것 같았다. 

 


임시저장에 있길래 확인했는데, 

 

이 글을 왜 쓰기 시작한 건지;  다음부터 쓸데없는 글 좀 쓰지 말아야겠다. 

 

 

 

 

 

 

 

 

 

 

 

 

  

728x90

'Node.js' 카테고리의 다른 글

0527 수업내용.  (0) 2021.05.27
카카오 로그인 맛보기  (0) 2021.05.21
[Node.js]서버 파일 분산  (0) 2021.05.01
0424 수업  (0) 2021.04.24
[Node.js] 0421 수업  (1) 2021.04.21
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함