Back to top

Blazor Pagenation 구현

작성날짜 2024/08/28

Pagenation이 필요한 이유


기존에는 그냥 DB에서 모든 글을 불러다가 표시해줬다.

posts = await db.Posts.ToListAsync();

하지만 이럴 경우, 한 화면에 너무 많은 글 목록이 생성되어 사용자가 불편하고 서버 입장에서도 매번 많은 수의 데이터를 처리해야 되니 부하가 발생할 수 있다.


한 페이지에 displayPostNumber의 개수만큼 보여주기 위해 아래와 같이 DB에서 데이터를 받아오는 코드를 수정했다.

tempPosts = await db.Posts.Skip((page - 1) * displayPostNumber)
                          .Take(displayPostNumber)
                          .ToListAsync();

현재 페이지를 나타내는 page 변수를 만들고, 현재 페이지 전의 post의 갯수를 계산하여 건너뛰고 displayPostNumber개 만큼만 가져온다.


이것으로 매 요청마다 DB에서 모든 글을 불러오는 참사를 막았다.


나눠서 보여주기


이제 이 불러온 데이터가 몇번째 페이지인지, 몇페이지가 남았는지와 이전/다음 페이지로 이동하는 버튼을 사용자에게 보여줘야한다.


rte_image_92.png출처: https://canvas.workday.com/components/navigation/pagination/

바로 이런걸 만들어야 한다.


내가 구상한 건

rte_image_12.png

이렇게 맨 처음 페이지, 맨 마지막 페이지 그리고 현재 페이지의 앞뒤 페이지 몇개를 보여주는 구성이다.


이를 위해서

  • 총 컨텐츠 수
  • 한 페이지에 보여줄 컨텐츠 수
  • 현재 페이지
  • 앞 뒤로 만들 버튼의 수

이렇게 4개가 필요하다.


먼저 총 페이지 수를 계산한다. 총 페이지 수는 컨텐츠 수를 한 페이지에 보여줄 컨텐츠 수로 나눈 뒤 소숫점을 올림해주면 된다.

// 총 페이지 수 = 총 컨텐츠 수 / 한 페이지에 보여줄 컨텐츠 수
void CalcTotalPageNum()
{
    var result = Math.Ceiling((double)TotalContentsNum / ShowContentsNum);
    totalPageNum = (int)result;
}


그 후 앞 뒤로 만들 버튼의 페이지 번호를 계산한다. 현재 페이지에서 몇 번째 전/후까지의 버튼을 보여줄지 그 수를 빼거나 더하면 된다.

만약, 현재 페이지가 14이고 앞뒤로 2개의 버튼을 표시하고 싶으면 시작 페이지 번호 = 14 - 2, 마지막 페이지 번호 = 14 + 2이다.

그리고 혹시 우리가 계산한 lasttotalPageNum보다 클 수도 있으므로 totalPageNum보다 작은지도 검사한다.

var start = CurrentPage - sideShowNum;
var last = CurrentPage + sideShowNum;
last = last > totalPageNum ? totalPageNum : last;


리스트에 반복문을 이용해 페이지 번호를 담아주면 된다.

맨 처음엔 currIndex가 12이므로 showPageGruoop의 첫 번째 원소는 12, 두 번째는 13... 마지막 원소는 16이 된다.

var currIndex = start;
while (currIndex < last + 1)
{
showPageGruop.Add(currIndex);
currIndex++;
}


만약, start가 1보다 작은 경우엔 1부터 넣어주자

if (start < 1)
{
for (int i = 1; i < last + 1; i++)
    {
     showPageGruop.Add(i);
    }
    return;
}


맨 앞으로 가는 버튼, 맨 뒤로 가는 버튼은 수동으로 넣어주면 완성이다.


관련글

Blazor에서 Db요청이 안 될때 / valid antiforgery token was not provided with the request. Add an antiforgery token, or disable antiforgery validation for this endpointBlazor MarkupString에 스타일 입히기Blazor에서 mainlayout의 요소를 다루기Blazor Server App SignOutAsync() 후에 AuthorizeView가 업데이트 되지 않는 문제
An unhandled error has occurred. Reload 🗙