관리 메뉴

새로운 시작, GuyV's lIfe sTyle.

닷넷 게시판 만들기 Part 47 본문

ⓟrogramming/asp.net 게시판

닷넷 게시판 만들기 Part 47

가이브 2011.06.17 15:56

2011/05/13 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 31
2011/05/16 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 32
2011/05/18 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 33
2011/05/19 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 34
2011/05/23 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 35
2011/05/25 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 36
2011/05/26 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 37
2011/05/27 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 38
2011/05/30 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 39
2011/05/31 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 40
2011/06/01 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 41
2011/06/08 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 42
2011/06/09 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 43
2011/06/13 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 44
2011/06/14 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 45
2011/06/15 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 46



1. 닷넷 개발환경 준비, 테스트
2. 닷넷 알아보기 [7/7]
3. asp.net 컨트롤 [10/10]
4. 데이터베이스(DB) [7/7]
5. 닷넷 게시판을 만들어보기 전에.. [4/4]
6. 게시판 만들기 [17/..]



하단에 게시판 링크를 만들어보기 전에, 페이징을 적용하면서 수정해야 되는 것들을 수정해보자.





눈에 띄는 문제점으로는 글목록에서 앞에 붙는 번호가 잘못 매겨져 있다.
앞서 우리는 '실제 존재하는 게시물 전체 갯수'에서 무조건 하나씩 감소시키게 했었는데, 페이징을 하면서 DataTable 로 넘어오는 갯수는 무조건 10개로 넘어온다. 그리고 마지막 페이지는 10개 이하이다.

일단 페이징은 무조건 10개로 넘어오기 때문에 이 정보만으로는 현재 페이지에 대한 번호를 매길 수가 없다. 구현 방법을 생각해보면 전체 글 갯수에서, 현재 페이지에 대한 시작번호만 알면 되는데, 여기서 필요한 정보는 (1)'전체 글 수' 정보가 무조건 필요하다. 우리는 앞에서 TOTAL_COUNT 를 따로 구해놨기 때문에 이를 이용할 수 있다. 그리고 (2)끊어지는 단위(페이지당 글 수)를 알아야 현재 페이지에 대한 시작 번호를 알 수 있다. 2페이지라면 전체갯수에서 (1페이지의 갯수+1)을 빼버리면 된다. 5페이지라면 총 4개의 페이지가 앞에 존재하므로 ((4*한페이지 당 갯수)+1) 부터 -1씩 감소시키면 되는 것이다. 그러니까 필자처럼 131개는 총 14페이지가 나온다. 마지막 페이지는 1개의 글이 존재하게 되겠다. 1페이지는 131번부터 10개, 121번까지가 매겨지고, 2페이지는 120부터 시작해야한다.

앞서 Repeater 이벤트인 rptList_Bound(..) 에 번호를 Label 컨트롤에 넣었는데, 이것을 조금 수정하자.



 void rptList_Bound(object sender, RepeaterItemEventArgs e)
 {
  // 시작번호는 전체 갯수에서 현재 페이지의 시작을 구하면 됨 
  int VIRTUAL_NUM = TOTAL_COUNT - e.Item.ItemIndex - ((NOW_PAGE-1) * 10) ;
  ((Label)e.Item.FindControl("lblNum")).Text = VIRTUAL_NUM.ToString();
 }



자, 여기서 빨간색 상수는 페이지 당 글 수인데, 이 정보는 Board 라이브러리에 속성으로 정의되어 있다. rptList_Bound 에서 Board 클래스를 인스턴스 화 시킨 후 사용하면 되지만, 이녀석은 최소 10번 이상 돌아가게 된다.
그래서 Page_Load() 에 있는 BOARD_LIB 이름으로 사용하는 Board 클래스 인스턴스를 '클래스 변수'로 지정하여 전역에서 사용가능하게 하자.




21번째 줄처럼 aspx 파일의 클래스단에 정의(메모리에 잡아놓지만 사용하지는 못한다)하고, Page_Load() 되면 이를 인스턴스화 한다. 그리고 뒤에 나오는 인스턴스 시키는 코드는 삭제한다. 이렇게 되면 rptList_Bound(..) 이벤트에서도 바로 사용가능게 되겠다.


void rptList_Bound(object sender, RepeaterItemEventArgs e)
{
// 시작번호는 전체 갯수에서 현재 페이지의 시작을 구하면 됨
int VIRTUAL_NUM = TOTAL_COUNT-e.Item.ItemIndex-((NOW_PAGE-1) * BOARD_LIB.PAGE_SIZE) ;
((Label)e.Item.FindControl("lblNum")).Text = VIRTUAL_NUM.ToString();
}



그리고 링크도 해결하자. 앞으로 현재 페이지를 계속 가지고 있어야 [리스트로..] 링크를 누를 때 리스트에서의 페이지를 계속 유지할 수 있다. 검색 기능과 마찬가지이다. 'page'라는 변수명으로 하기로 했으니, 이대로 걸어주자.






반전된 코드가 추가된 코드이다. 변수들은 모두 정의를 해놓았기 때문에(클래스 변수로) 그대로 사용하면 그만이다. 그리고 글 읽는 페이지인 board_view.aspx 에서도 값을 받고 다시 넘겨주도록 수정해야 할 것이다. "글쓰기"는 별 의미 없으니 놔두기로 한다. 변수명도 board_list.aspx 에서와 동일하게 한다. 별도의 페이징에 관련된 코드는 필요없다.





그리고 받은 NOW_PAGE를 [리스트] 링크에 붙여서 카테고리 구분 값처럼  board_list.aspx 로 보내주자.






그림처럼, 5페이지의 리스트에서 글읽기 페이지로 이동하고 [리스트] 이동 링크에 마우스를 대었을 때 볼 수 있는 링크된 주소이다. 지금은 페이지 링크(이전/다음 또는 숫자 1,2,3,4...)가 구현되지 않았기 때문에 페이지 이동을 하려면 직접 주소에 값을 붙여줘서 테스트해야 한다.

이제 리스트 하단에 리스트를 만들어보자. 일단 디자인을 해보도록 한다. 하단에 테이블로 좌측과 우측으로 나누고, 좌측에는 간단하게 '이전페이지 / 다음페이지'링크를 만들어보고, 우측에는 숫자로 표시하여 특정 페이지에 직접 이동할 수 있도록 구현해보자. 이는 모두 Label 컨트롤로 만든다. 좌측을 lblPageMove1, 우측을 lblPageMove2 로 하자.

<br>

<table width="600">
<tr bgcolor="#eeeeee">
 <td width="50%">
  <ASP:Label id="lblPageMove1" runat="server">이전페이지 / 다음페이지</ASP:Label>
 </td>

 <td width="50%" align="right">
  <ASP:Label id="lblPageMove2" runat="server">[이전10] <b>1</b> 2 3 4 5 6 7 8 9 10 [다음10]</ASP:Label>
 </td>
</tr>
</table>

<br><br>



 



대략 위의 형식대로 만들자.

먼저 이전페이지 / 다음페이지를 구현하기 위해 고민을 해보자.
기능상 현재 페이지번호에서 이전페이지로 이동하려면 (현재페이지-1) 페이지로 이동하면 되고, 다음페이지는 (현재페이지+1) 페이지로 이동하면 된다. 단, 이전페이지로 갈 수 있는 조건과 다음페이지로 갈 수 있는 조건이 있을 수 있다. 지금 페이지가 1페이지면 이전 페이지는 0페이지이므로 의미가 없다. 링크를 아예 없애주기로 하자. 그리고 지금 페이지가 막지막페이지면 다음 페이지는 존재하지 않으므로 의미가 없다. 이 때도 링크를 아예 없애주기로 한다.

이 기능을 각각을 라이브러리에서 메서드로 만들기로 한다. 이 메서드에서는 간단하게 페이지 이동 링크를 만들어 string 으로 리턴해주자. 구현하기 위해 필요한 정보는 무엇일까? 생각해보면 기본적으로 현재페이지 번호, 총 페이지 수 정도가 되겠다. 

또 중요한 이슈가 있는데, 우리 게시판만 봐도 현재 기본적으로 '카테고리'값이 붙고 '검색'에 관련된 변수 2개가 더 붙을 수 있다. 이 외에 게시판의 성격에 따라 어떤 변수와 해당 값이 붙을지 모르기 때문에, 함께 넘길 값을 받아서 링크해주기로 하자. 이 매개변수는 단순히 GET 형식의 string 으로 입력받게 한다. 우리는 c, stype, svalue 이렇게 세 가지를 사용하게 될 것이다. 

그리고 하나 생각할게 바로 현재 리스트의 페이지 이름이다. 우리 게시판은 지금 board_list.aspx 파일명으로 사용되지만, 이 역시 누가 어떤 파일이름으로 리스트 페이지를 구성하고 이 라이브러리를 땡겨쓸지 모른다. 그러므로 <a href=".."> 에 들어갈 페이지 파일명을 직접 받는 방법이 있지만, 여기서는 Request.ServerVariables 컬렉션을 이용해보겠다. Request.ServerVariables 컬렉션은 서버의 정보와 접속하는 사람의 정보등을 담고 있는 유용하게 사용되는 녀석이다. (Part 12 에서 잠깐 다루었었다) 여기에서 현재 열려진 파일명의 정보도 담고 있다. 이름은 "SCRIPT_NAME"으로, Request.ServerVariables["SCRIPT_NAME"] 이렇게 string 을 이용하면 된다.

게다가.. (^^) page 라는 변수 자체도 우리가 임의로 정했다. 혹시 다른 게시판 개발자가 페이지값을 넘기는 GET 변수로 'page'가 아닌 'p'로 했을때는? 이 역시 골치아픈 일이니 이 녀석도 함께 받아주자.

#참고
예전에 말했지만 라이브러리에서 제공하는 메서드는 특정 기능에 국한되지 않고 독립적으로 구성하는게 좋다 라고했다. 이 라이브러리를 이용하는 게시판에서 기능상으로 '이전페이지, 다음페이지'는 지금의 형식처럼 단순한 문자열로만 구성될 수도 있겠지만 어쩌면 이미지로 화살표 추가하여 디자인을 표시할 수도 있다. 그렇기 때문에 더 필요하다면 "이전페이지"에 표시될 문자열과 "다음페이지"에 표시될 문자열을 인수로 따로 입력받아서 그걸로 적용해주면 라이브러리 메서드로서의 역할을 제대로 할 수 있다. 최대한 땡겨 쓰는 입장을 생각해서 만드는게 좋은 방법이다. 



이전페이지/다음페이지 링크를 생성하는 메서드를 Board.cs 에서 구현해보자.

* 위의 소스상 172번째 줄의 '이전페이지'문자열 앞에 실수로 '◀'문자가 빠졌습니다. 참고하세요.


좀 길고 복잡해 보이지만, [이전페이지] 조건에 따라 링크를 해주고, [다음페이지]도 마찬가지로 조건에 따라 링크를 해주는 string을 하나 계속 값을 붙여가며 만든다. 그리고 마지막에 Label 컨트롤을 생성해서 Text 속성에 넣어 리턴하는 기능이다. 과정은 주석으로 모두 달아두었으니 분석해보시기 바란다. 그리고 Request.ServerVariables 는 라이브러리인 DLL 에서 바로 사용하지 못하기 때문에 HttpContext.Current 를 앞에 붙여준다. 

이제 다음처럼 board_list.aspx 리스트페이지에 라이브러리를 적용하면 잘 작동할 것이다.

 



페이징 기능을 구현할 시점에 말씀드렸지만, 실제 페이징 자료와 지금의 페이지 이동 링크 기능은 사실상 분리되었다고 생각하면 된다. 페이징 기능 뿐만 아니라, 복잡한 프로그램에 모두 해당한다. 웹프로그래밍이 어렵고 헷갈리는 이유 중 하나가 기능상으로 어떤 녀석과 관련이 있는지 없는지 잘라서 분리하기가 힘들기 때문이다. 늘 태그는 따라다니고, 문자열 결합해줘야 하고, 어떤 기능이랑 엮어야 되고, 컨트롤끼리 놀기도 하고..

개념을 먼저 알고 접근하면 쉽게 구분이 가능하지만, 일반적으로 다들 결과를 먼저 보길 원하기 때문에 이러한 개념은 다시 잡기가 힘들다. 특히 처음부터 '개발 툴(Visual Studio 등)'을 이용하면 더욱 그렇다. 선입견을 버려야 쉬운게 프로그램 개발이다. 원리를 알면 뭐든지 쉽다.


다음 시간에 오른쪽에 있는 lblPageMove2.Text 를 마무리해보자. 예습은 필수이다.
그리고 압축 파일은 이때까지 진행한 전체 소스파일이다.




그럼..

0 Comments
댓글쓰기 폼