제목: 상세 페이지 구성 (Client)
최초작성일: 2014-12-30
최종수정일: 2014-12-30
연말연시는 언제나 아쉬움이 많이 남는 것 같습니다. 그래도 이번 연말은 좋네요. 회사란 곳에 입사를 하고서부터는 정말 바쁘게 시간이 흘러가서 따로 한 해를 정리할 시간이 없었는데 좋은건지 안좋은건지 올해는 지나온 시간들 중 가장 한가한 연말이 아닌가 합니다. 지나온 바쁜 시간들에 물론 감사하는 마음도 있지만 올해처럼 이런 여유를 가질 수 있는 연말도 퍽이나 좋네요. 모두에게 다사다난했을 2014년도 잘 정리하시기 바랄게요. 지난 시간에는 목록 페이지를 개발해 보았습니다. 비록 아직 서버가 없는 관계로 인터페이스는 없지만 단말에서 데이터를 생성하여 UI에 Binding 하고, Binding 하는 부분의 모듈을 Templates을 사용하여 개선하는 부분도 진행해 보았습니다. 이번에는 상세 페이지를 만들어 보겠습니다. 상세 페이지는 목록에서 볼 수 없는 해당 게시물에 대한 전체 정보를 조회하는 기능을 제공하는 페이지입니다. 우리가 만들 게시판은 정보가 많지 않기 때문에 목록 페이지에 보이는 데이터가 거의 다지만, 실제 프로젝트에서는 정말 많은 데이터를 모바일 화면에서도 조회하게 됩니다. 자 그럼 상세 페이지 개발을 시작해보겠습니다. 상세 페이지 역시 [헤더] - [본문] - [푸터]로 영역을 분할하여 구성하겠습니다. 아래 소스 코드를 참고하셔서 ./bbs_detail.html 파일로 저장합니다.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 31 32 | <! DOCTYPE html> < html lang = "ko" > < head > < meta http-equiv = "content-type" content = "text/html;charset=UTF-8" > < meta name = "viewport" content = "user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width" > < title >Mobile BBS</ title > < link rel = "stylesheet" type = "text/css" href = "./css/common.css" /> </ head > < body > < header > < h1 >Mobile BBS</ h1 > </ header > < div class = "wrap" > < div class = "content_line" > < span id = "subject" ></ span > </ div > < div class = "content_line" > < span id = "additionalInfo" ></ span > </ div > < div class = "content_line" > < span id = "content" ></ span > </ div > </ div > < footer > < button id = "btnWrite" >글쓰기</ button > </ footer > </ body > < script type = "text/javascript" charset = "utf-8" src = "./scripts/jquery-1.10.2.min.js" ></ script > < script type = "text/javascript" charset = "utf-8" src = "./scripts/common.js" ></ script > </ html > |
그럼 이제 상세 페이지의 모양을 위해 간단하게 StyleSheet를 추가해보겠습니다. StyleSheet는 모든 페이지에서 common.css를 사용하도록 하겠습니다. common.css에 상세 페이지와 관련된 부분을 추가해보겠습니다.
1 | .wrap .content_line{ padding : 7px 5px 7px 5px ; border-bottom : 1px solid #ccc ;} |
여기서 정보를 전달하는 방법에 크게 두 가지 방법이 있습니다. 먼저 일반적인 방법으로 게시물의 식별자(Key) 정보만 전달하고 상세 페이지에서 식별자로 해당 게시물 정보를 조회해오는 방법이 있습니다. 하지만 우리가 개발하는 게시판처럼 목록에서 보여지는 내용과 상세에서 보여지는 컬럼 수가 많이 차이나지 않는다면 목록을 조회할 때 모든 정보를 조회한 후 상세 페이지에서는 별도의 서버 인터페이스를 하지 않는 방법이 있습니다. 우리는 후자의 방법을 선택하여 목록 페이지에서 모든 데이터를 받아서 상세 페이지로 전달하기로 하겠습니다. 데이터를 전달하는 방법에 대한 고민도 필요합니다. 만약 어플리케이션이 하나의 HTML로 이루어진 구조라면 전역 변수를 사용할 수도 있습니다. 하지만 업무 별로 페이지를 분할하여 개발하는 경우에는 전역 변수를 공유할 수 없으므로, 어떤 방식으로던 데이터의 전달이 필요합니다. 전달하는 방법은 크게 두 가지로 나눌 수 있을 것 같습니다.
먼저 쿼리스트링으로 전달하는 방법입니다. 이동할 페이지 정보 뒤에 쿼리스트링으로 값을 연결하여 보내는 경우 받는 페이지에서 location.href 정보에서 쿼리스트링 정보를 잘라서 사용할 수 있습니다. 쿼리스트링으로 데이터를 전달할 경우 아래와 같은 코드로 손쉽게 잘라올 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var REQUEST = {}; REQUEST.getParameter = function (parm) { var parmVal = null ; var pageUrl = location.href; var parms = (pageUrl.slice(pageUrl.indexOf( "?" ) + 1, pageUrl.length)).split( "&" ); for ( var inx=0; inx<parms.length; inx++) { if (parms[inx].split( "=" )[0].toUpperCase() == parm.toUpperCase()) { parmVal = decodeURIComponent(parms[inx].split( "=" )[1]); break ; } } return parmVal; }; |
두 번째 방법을 선택한 이유는 Android의 4.0.x 대 일부 단말의 OS에서 쿼리스트링까지 페이지 파일명으로 인식하는 버그가 있고, 글 본문 내용 같은 큰 데이터 전달을 위함입니다. 쿼리스트링은 1024 바이트까지만 전달 가능합니다. 그럼 이전 시간에 개발했던 ./scripts/common.js 파일을 열어 Local Storage 저장 및 페이지 이동에 대한 기능을 개발하겠습니다. common.js 파일에 아래 내용을 추가합니다.
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 | COMM.setItem = function (key, value) { var saveValue = ( typeof value == 'string' ) ? new String(value) : JSON.stringify(value); localStorage.setItem(key, saveValue); }; COMM.getItem = function (key) { var value = localStorage.getItem(key); try { value = JSON.parse(value); } catch (e) { } return value; }; COMM.removeItem = function (key) { localStorage.removeItem(key); }; COMM.movePage = function (page, pageData) { if (pageData) COMM.setItem( '__pageData' , pageData); location.href = page; }; COMM.getPageData = function () { var data = COMM.getItem( '__pageData' ); COMM.removeItem( '__pageData' ); return data; }; |
이제 목록 페이지를 수정하여 게시물을 터치하면 상세 페이지로 이동하도록 수정하겠습니다. 목록 데이터를 Bind하는 function인 BBS.display function을 아래와 같이 수정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | BBS.display = function (rows) { var listArea = $( '#bbsListArea' ); var html = null ; COMM.loadTemplate( 'bbs_list_line' , function () { for ( var inx=0; inx<rows.length; inx++) { html = COMM.getHTMLObj( 'bbs_list_line' , rows[inx]); html.find( '.bbs_list_txt' ).attr( 'data' , rows[inx]); html.find( '.bbs_list_txt' ).on( 'click' , function (event) { COMM.movePage( './bbs_detail.html' , $( this ).attr( 'data' )); }); listArea.append(html); } }); } |
1. ./bbs_detail.html 페이지로 이동하는지(물론 헤더와 푸터만 있는 빈 페이지입니다.)
2. Chrome 브라우저의 localStorage에 __pageData 값이 잘 저장되어 있는지
위 두 가지 사항을 확인해 보겠습니다. Google Chrome에서 마우스 우클릭 후 나타나는 바로가기 메뉴에서 [요소 검사]를 선택하거나 [F12] Key를 누르면 구글 개발자 도구가 열립니다. 먼저 페이지 이동에 대한 부분은 상세 보기 페이지로 이동하고 Console에 JavaScript 오류가 표시되는 내용이 없다면 정상으로 구현된 것입니다. localStorage 값 확인은 Google 개발자 도구의 Resources 탭에서 확인할 수 있습니다. 아래 그림과 같이 Resources 탭을 확인해보면 데이터 저장 여부를 확인할 수 있습니다.
다른 방법으로 개발자 도구의 Console에서 직접 COMM.getItem function을 호출하여 확인해볼 수 있습니다.
위 내용이 모두 정상적으로 확인되었다면 다음 Step으로 넘어가볼까요?
이제 목록 페이지에서 전달한 데이터를 받아서 상세 페이지에 Bind하는 부분을 구현해보겠습니다. 상세 페이지에서 사용할 JavaScript 파일은 ./scripts/bbs_detail.js 로 생성하여 아래 코드를 반영합니다.
1 2 3 4 5 6 7 8 9 10 11 | var DETAIL = {}; DETAIL.display = function (data) { $( '#subject' ).text(data.subject); $( '#additionalInfo' ).text(data.updateDate + ' | ' + data.inputUserName + ' (' + data.readCount + ')' ); $( '#content' ).text(data.content); }; $(document).ready( function () { DETAIL.display(COMM.getPageData()); }); |
1 | < script type = "text/javascript" charset = "utf-8" src = "./scripts/bbs_detail.js" ></ script > |
여기까지 모두 잘 되실거라 믿겠습니다. 그런데 지금은 값을 표시할 부분이 3군데 밖에
없어서 코딩이 짧게 끝났지만 값을 20개, 30개 세팅해야 한다고 하면 Selector로 Element를 찾아서 값을 세팅하는
코딩이 20 라인이 들어가게 됩니다. 그럼 이제 위에서 만든 Template을 이용해서 코딩을 좀 짧게 할 수 있는 방법으로
다시 개발해 보겠습니다.
먼저 기본 HTML 페이지를 아래와 같이 수정합니다.
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 31 32 33 34 35 | <! DOCTYPE html> < html lang = "ko" > < head > < meta http-equiv = "content-type" content = "text/html;charset=UTF-8" > < meta name = "viewport" content = "user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width" > < title >Mobile BBS</ title > < link rel = "stylesheet" type = "text/css" href = "./css/common.css" /> </ head > < body > < header > < h1 >Mobile BBS</ h1 > </ header > <!-- 수정 시작 --> < div class = "wrap" style = "display:none;" > < div class = "content_line" > < span >{subject}</ span > </ div > < div class = "content_line" > < span >{additionalInfo}</ span > </ div > < div class = "content_line" > < span >{content}</ span > </ div > </ div > <!-- 수정 종료 --> < footer > < button id = "btnWrite" >글쓰기</ button > </ footer > </ body > < script type = "text/javascript" charset = "utf-8" src = "./scripts/jquery-1.10.2.min.js" ></ script > < script type = "text/javascript" charset = "utf-8" src = "./scripts/common.js" ></ script > < script type = "text/javascript" charset = "utf-8" src = "./scripts/bbs_detail.js" ></ script > </ html > |
1 2 3 4 5 6 7 | DETAIL.display = function (data) { var area = $( '.wrap' ); var html = COMM.dynamicExpression(area.html(), data); area.empty(); area.html(html); area.show(); } |
그럼 목록에서 데이터를 전달할 때 additionalInfo 컬럼을 세팅해서 보내보도록 하겠습니다. bbs_list.js 파일을 열어 BBS.display 함수에 컬럼을 추가해 보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | BBS.display = function (rows) { var listArea = $( '#bbsListArea' ); var html = null ; COMM.loadTemplate( 'bbs_list_line' , function () { for ( var inx=0; inx<rows.length; inx++) { rows[inx].additionalInfo = rows[inx].updateDate + ' | ' + rows[inx].inputUserName + ' (' + rows[inx].readCount + ')' html = COMM.getHTMLObj( 'bbs_list_line' , rows[inx]); html.find( '.bbs_list_txt' ).attr( 'data' , JSON.stringify(rows[inx])); html.find( '.bbs_list_txt' ).on( 'click' , function (event) { COMM.movePage( './bbs_detail.html' , $( this ).attr( 'data' )); }); listArea.append(html); } }); } |
'모바일 > 게시판만들기' 카테고리의 다른 글
[하이브리드앱 만들기] 모바일 간단 게시판 #4 - 글쓰기 페이지 (0) | 2015.01.05 |
---|---|
[하이브리드앱 만들기] 모바일 간단 게시판 #2 - 목록 페이지 (2) | 2015.01.04 |
[하이브리드앱 만들기] 모바일 간단 게시판 #1 (0) | 2015.01.01 |