Tips by아포리아 postedOct 01, 2016

댓글ajax로 불러오는 거 포기 직전...;;;;;

Views 789 Likes 0 Replies 16
Extra Form
입금자 성명 윤삼
필요장비 빔프로젝터,마이크
대관시간 1300
신청공간 세미나실
대관일 2011-10-10

 

전에도 한번 이런 글( https://www.xetown.com/qna/559820 )을 쓴 적이 있는데, 실패와 고난과 좌절의 연속이네요ㅠ

아직은 절반의 성공, 또는 절반의 실패쯤이라고 할 수 있는데,

반쯤은 하소연, 반쯤은 자랑 삼아 글 하나 남겨봅니다.

 

 

대댓글만 따로 불러내기 위해, 우선 댓글단에서 (대댓글이 아닌) 최상위 댓글만 모아서 리스트로 만들었었습니다.

일단 아래처럼 쿼리를 짜고, 게시판 스킨에 queries폴더를 만들어 그 안에 넣었죠.

 

원댓글 개수 구하는 쿼리,

<query id="getCommentCountByDepth0" action="select">
    <tables>
        <table name="comments_list" />
    </tables>
    <columns>
        <column name="count(*)" alias="count" />
    </columns>
    <conditions>
        <condition operation="equal" column="comments_list.document_srl" var="document_srl" filter="number" pipe="and" />
        <condition operation="equal" column="comments_list.depth" default="0" pipe="and" />
    </conditions>
</query>

그리고 리스트를 불러오는 쿼리도 만들어 넣었습니다.

<query id="getCommentPageListByDepth0" action="select">
    <tables>
        <table name="comments" alias="comments" />
        <table name="comments_list" alias="comments_list" />
    </tables>
    <columns>
        <column name="comments.*" />
        <column name="comments_list.depth" alias="depth" />
    </columns>
    <conditions>
        <condition operation="more" column="comments.status" var="status" pipe="and" />
        <condition operation="equal" column="comments_list.document_srl" var="document_srl" notnull="notnull" pipe="and" />
        <condition operation="equal" column="comments_list.comment_srl" var="comments.comment_srl" filter="number" pipe="and" />
        <condition operation="more" column="comments_list.head" default="0" pipe="and" />
        <condition operation="equal" column="comments_list.depth" default="0" pipe="and" />
    </conditions>
    <navigation>
        <index var="list_order" default="comments_list.head" order="desc" />
        <list_count var="list_count" default="list_count" />
        <page_count var="page_count" default="10" />
        <page var="page" default="1" />
    </navigation>
</query>

 

_comment.html 파일에서는 위에서 만든 최상위의 원댓글 리스트에 다음과 같이 commentItem()을 집어넣고(얘가 있어야 프로필 이미지 같은 걸 손쉽게 가져올 수 있거든요) 페이지네이션도 재정렬을 했습니다.

{@
    $oModuleModel = getModel('module');
    $comment_config = $oModuleModel->getModulePartConfig('comment',$module_info->module_srl);
    $query_path = $module_info->module.'/skins/'.$module_info->skin;

    $args = new stdClass();
    $args->document_srl = $oDocument->document_srl;
    $ccbd = executeQuery($query_path.'.getCommentCountByDepth0', $args);
    if(Context::get('cpage')):
        $cpage = Context::get('cpage');
    else:
        if(!$mi->cmt_lst):
            $cpage = 1;
        else:
            $cpage = (int)(($ccbd->data->count-1)/$comment_config->comment_count)+1;
        endif;
    endif;
    $args->list_count = $comment_config->comment_count; // 게시판 관리 페이지에서 설정한 페이지당 댓글 개수
    $args->page = $cpage;
    if(!$mi->cmt_pg):
        $args->page_count = 5;
    else:
        $args->page_count = $mi->cmt_pg;
    endif;

    $output = executeQuery($query_path.'.getCommentPageListByDepth0', $args);
    foreach($output->data as $key => $val):
        $oCommentItem = new commentItem();
        $oCommentItem->setAttribute($val);
        $comment_list[$val->comment_srl] = $oCommentItem;
    endforeach;

    if($output->total_page>1) $oDocument->comment_page_navigation = $output->page_navigation;
}

이렇게 만든 $comment_list 변수를 반복문으로 돌림으로써, 보통의 댓글단에서처럼 목록을 구성할 수 있게 됐습니다.

 

보통은 대댓글이 나오다가 중간 페이지가 넘어가고 그러잖아요?

그치만 이렇게 하면 페이지 나눔의 기준이 원댓글로 list_count되는 것이 장점인 것 같아요ㅎㅎ

즉, 목록이 최상위 댓글로만 이뤄졌다는 점이 일반 댓글 목록과 다른 점이죠.

여기까지는 무사히 성공!

 

그럼, 대댓글들은 어디로 가는가...

이른바 대댓글 접기, 또는 대댓글 감추기라고 하죠.

(1)대댓글 목록은 접어놓고, (2)원댓글 부분에 '답글(n)'처럼 보이게 링크를 만든 뒤, (3)링크를 클릭하면 대댓글 목록을 보게 할 수 있습니다.

 

우선 원댓글에 딸려 있는 대댓글들의 개수를 구하는 쿼리를 짜서 마찬가지로 새로 만든 quaries 폴더에 넣었습니다.

<query id="getDescendantCommentCount" action="select">
    <tables>
        <table name="comments_list" />
    </tables>
    <columns>
        <column name="count(*)" alias="count" />
    </columns>
    <conditions>
        <condition operation="equal" column="comments_list.head" var="comment_srl" filter="number" pipe="and" />
        <condition operation="more" column="comments_list.depth" default="1" pipe="and" />
    </conditions>
</query>

여기서 head는 원댓글의 comment_srl이기도 한데, parent_srl이 대댓글의 바로 직전 부모 댓글의 번호라면, head는 (댓글 depth와 상관없는) 최초의 시조 댓글의 번호더군요.

그래서 이걸로 count를 구하는 쿼리를 짜본 겁니다.

실사용할 때는 (원댓글의 head까지도 포함하기 때문에) 1을 뺄셈해줘서 사용하면, 원댓글에 딸린 전체 대댓글들의 개수가 됩니다.

 

그리고 이번에는 원댓글과 head를 공유하는 대댓글들만 모으는 리스트를 위해 쿼리 하나를 더 짰습니다.

<query id="getDescendantCommentList" action="select">
    <tables>
        <table name="comments" alias="comments" />
        <table name="comments_list" alias="comments_list" />
    </tables>
    <columns>
        <column name="comments.*" />
        <column name="comments_list.depth" alias="depth" />
        <column name="comments_list.head" alias="head" />
    </columns>
    <conditions>
        <condition operation="more" column="comments.status" var="status" pipe="and" />
        <condition operation="equal" column="comments_list.comment_srl" var="comments.comment_srl" filter="number" pipe="and" />
        <condition operation="equal" column="comments_list.head" var="comment_srl" filter="number" pipe="and" />
        <condition operation="more" column="comments_list.depth" default="1" pipe="and" />
    </conditions>
    <navigation>
        <index var="list_order" default="comments_list.comment_srl" order="asc" />
        <list_count var="list_count" default="list_count" />
        <page_count var="page_count" default="10" />
        <page var="page" default="1" />
    </navigation>
</query>

depth가 1 이상인 댓글만 수집하므로, head 번호가 같더라도 원댓글은 목록에서 빠지게 돼죠.

 

그리고 현재 이 쿼리로 만든 리스트는 _comment.html의 적당한 위치에 아래처럼 넣어서 잘 사용하고 있습니다.

{@
    $args = new stdClass();
    $args->comment_srl = $comment->comment_srl;
    $dcc = executeQuery($query_path.'.getDescendantCommentCount', $args); // $dcc->data->count로 자손 댓글의 개수를 표현하는 게 가능해집니다.
}

{@
    $args = new stdClass();
    $args->document_srl = $oDocument->document_srl;
    $args->comment_srl = $comment->comment_srl;
    $args->list_count = $dcc->data->count;
    $args->page = 1;
    $args->page_count = 5;

    $o_output = executeQuery($query_path.'.getDescendantCommentList', $args);
    $o_comment_list = [];
    foreach($o_output->data as $key => $val):
        $oCommentItem = new commentItem();
        $oCommentItem->setAttribute($val);
        $o_comment_list[$val->comment_srl] = $oCommentItem;
    endforeach;
    if($o_output->total_page>1):
        $oDoc->comment_page_navigation = [];
        $oDoc->comment_page_navigation = $o_output->page_navigation;
    endif;
}

이로써 $o_comment_list는 특정 $comment->comment_srl을 head값으로 가지는 대댓글들의 리스트가 됐습니다.

 

마지막으로 _comment_re.html이라는 파일을 하나 새로 만들어서 대댓글 리스트 출력을 담당하게 했습니다.

이렇게요.

<ul class="fdb_lst_ul {$mi->fdb_hide}">
    <block loop="$o_comment_list=>$k,$cmt">
    <li id="comment_{$cmt->comment_srl}" class="fdb_itm clear re bg{($cmt->get('depth'))%2}" style="margin-left:30px">
        <i class="fa fa-share fa-flip-vertical re"></i>... 블라블라~~

그리고 이 파일은 _comment.html 내에 include 시켜서 가져오게 했지요.

 

여기까지는 흡족할 정도로 매우 잘 됩니다.

include한 대댓글 리스트를 display: none 처리했다가 jQuery로 _comment.html 내에서 링크를 클릭하면 보이게끔 만들었구요.

        <block cond="$dcc->data->count>1">
            <a class="meta_re_tg re_comment" href="#" style="text-decoration: none; background-color: #735763; color: white; letter-spacing: -1px; padding: 6px 7px; border-radius: 3px; opacity: 0.6;">{$lang->re_cmt} ({$dcc->data->count})</a> // 얘를 클릭하면
        </block>
    </li>
    <div class="comment_re_container" cond="$dcc->data->count" style="display:none"><include target="_comment_re.html" /></div> // 얘가 보이게 돼죠
</block> // 얘는 원댓글의 반복문이 끝나는 지점이에요

(a태그 안의 텍스트는 '답글 (n)'으로 나오게 됩니다.)

 

...

 

여기까지, 아무런 무리 없이 잘 됩니다.

하지만!!!!!! 제가 계획했던 건 ...

처음에는 대댓글 리스트를 로드하지 않았다가, 원댓글에서 '답글 (n)'이라는 링크를 클릭하면 ajax로 대댓글 리스트를 불러오게 하는 것이었습니다.

 

근데 이게 도무지 되지를 않습니다.

현재까지 시도해본 방법은 다음과 같습니다.

일단 include 구문을 지우구요...

 

1. load()로 컨테이너 $('.comment_re_container') 안에 _comment_re.html 파일을 불러온다.

    => 파일 퍼미션 때문인지, 무엇 때문인지 실패 ㅡㅡ;;

2. append() 또는 html()로 '<include target="_comment_re.html" />'을 새로 불러온다.

    => _comment_re.html 코드들의 따옴표 문제 때문인지 역시 실패합니다. 그래서 따옴표를 재정리하는 노가다를 해봤는데, 이미 코드 안에 홑따옴표와 겹따옴표가 중복되는 지점들이 있어서 그냥 포기;;;

3. exec_json으로 'board.dispBoardContentCommentList' 액션을 활용한다.

    => 이 방법은 불러올 수 있는 항목들이 제한적인 데다, 가장 결정적으로는 댓글의 head 번호를 따올 수 없어서 대댓글 필터링조차 어려워 포기ㅠㅠ

 

아무튼 이런 실패를 겪고 있는 중입니다 으흐흐흐

구글링을 하다보니, 외부페이지(php)로 db 테이블을 갖고 오는 방법이 있다고 하던데 다음에는 이 방법으로 실패를(?) 해보려구요.

 

...

 

능력의 한계를 실감하는 깊은 밤이네요.

다음에 또 (실패) 소식 전하도록 하겠습니다~

?
Comment '16'