페이지네이션 구현

HOU·2023년 4월 24일
post-thumbnail

페이지네이션 구현하기

현재 스벨트와 fast-api를 이것이 fast-api다를 통해 공부하고 있다. 그 중에 페이지네이션 관련해서 내용이 있었는데, 나의 입맛에 맞게 수정하고 페이지네이션에 대해 구현하는데 어려움을 느껴서 제대로 한번 공부해보기 위해서 시작했고, 공부한 내용 정리!

기존의 책 내용이 정말 좋으므로 공부하시려면 추천드리고 싶습니다.
이것이 패스트 api다.

기존 화면

첫 화면이다.

두 번째 화면이다.

번호를 누를 때 1~6번까지는 6개가 또 가장 끝의 6개의 숫자가 출력된다. 나는 이게 좀 사용자가 볼 때 어색할 수 있다고 생각했다. 이 어색함을 해소하고자 손을 대기 시작했다.

왜 그랬을까?

  • 생각보다 쉬울거라고 달려들었는데 역시나 세상에 쉬운 코드 하나없다.

기존 코드

{#each Array(total_page) as _, loop_page}
      {#if loop_page >= $page - 5 && loop_page <= $page + 5}
        <li class="page-item {loop_page === $page && 'active'}">
          <button
            on:click={() => get_question_list(loop_page)}
            class="page-link">{loop_page + 1}
 		 </button>
        </li>
      {/if}
{/each}

위에 보면 loop_page$page의 -5 +5 를 기준으로 아래 번호들이 나오게 되어있다. 1~6까지는 loop_page >= $page - 5 조건이 false 로 반환되므로 페이지 1번기준으로 -4~0 까지가 나오지 않는것이다. 이 와 같이 loop_page <= $page + 5total_counts ~ total_counts +5 의 숫자가 조건에 걸려 나오지 않았고, 5개 밖에 출력되지 않았다.

내가 원하는 것

  • 나는 어떤 상황에서든 10개의 페이지를 보고싶다.

구현에 필요한 것

크롤링을 해보니 아래와 같았다.

  • 화면에 그려질 페이지 그룹
  • 화면에 보여질 첫 번째 페이지
  • 화면에 보여질 마지막 페이지
  • 총 페이지 수

타 블로그들에는 대표적으로 위와같이 4개의 조건이 필요하더라, 다른 블로그를 따라도 잘 안되었다.페이지네이션에는 여러가지 방법이 있는 거 같고, 내가 구현한건 옳바르지 않은 방법 일 수도 있다.

난 왜 저 4개로 안되지..

  • svelte를 사용했는데, 다른 코드들은 해당 태그의 데이터를 remove 하는 방식으로 처리, svelte remove 하는 방법을 몰랐다. ㅠㅠ 정리하면서 든 생각. 왜 안찾아봣을까!?
  • 나의 코드는 0~30까지의 리스트를 반복해서 페이징이 구현되어 있었고, 이 리스트를 반복하면서 조건을 주면서 해결하다보니 일반적인 방법으로는 잘안되었다.

내가 필요한 것

  • 화면에 그려질 페이지 그룹의 시작하는 수
    • 1~10이면 1번째 그룹
    • 11~20이면 2번째 그룹
  • 전체 화면 수 (total_count)
  • 파이썬의 range처럼 그룹의 리스트를 불러 올 함수

변경한 코드

{#each customRange(start, start+10, total_page) as loop_page}
        <li class="page-item {loop_page === $page && 'active'}">
          <button
            on:click={() => get_question_list(loop_page)}
            class="page-link">{loop_page + 1}</button
          >
        </li>
{/each}

customRange라는 함수를 만들어서 내가 원하는 숫자가 담긴 배열을 만들었다.

function customRange(start, stop, total_page) {
    //보여지는것이다.
    if (start < 0) {
      start = 0;
    }
    if (stop > total_page) {
      stop = total_page;
    }
    return Array.from({ length: stop - start }, (_, i) => i + start);
  }

위 함수에서 제일 중요한건 Array.from 함수로 python 의 range함수와 비슷하게 구현했다.

마지막으로 해당 페이지의 데이터를 백엔드로 부터 호출하는 부분

function get_question_list(_page) {
    if (_page < 0) {
      _page = 0;
    }

    if (_page > total_page) {
      _page = total_page - 1;
    }
    let params = {
      page: _page,
      size: size,
    };
    fastapi("get", "/api/question/list", params, (json) => {
      question_list = json.question_list;
      $page = _page;
      total = json.total;
    });
    console.log("page", _page);
    start = Math.floor(_page / 10) * 10;
  }

여기서 주목할 것은 _page<0start = Math.floor(_page/10) * 10;이다.
하나는 음수가 되면 음수를 막는 거고, 하나는 이게 1~10, 11~20 의 시작포인트를 알기 위해서 작성해놓은 것이다.

적용

10개 씩 잘 적용되는 것을 확인할 수 있다.

profile
하루 한 걸음 성장하는 개발자

0개의 댓글