Dev

Node.js 무한 대댓글 로직 구현

Wermut 2025. 2. 27. 02:22

 

대댓글 DB 구성

 

댓글과 대댓글을 구현하기 위해선 DB에 필수적으로 필요한 칼럼이 존재한다.

 

  • com_idx : 댓글 및 대댓글을 구분할 auto increment 속성의 칼럼`
  • com_group : 대댓글의 상위 댓글(대댓글)의 com_idx이며 대댓글 이하의 대댓글을 로딩할 때 사용
  • depth : 댓글의 깊이를 지정함

 

comments 테이블의 구조

 

이 외에 부가적인 다른 요소들을 더 추가해 위 사진과 같은 테이블을 형성하였다.

 

댓글 기능이 적용될 problem 페이지

 

위 사진은 댓글 기능이 적용될 problem 페이지이며 댓글 부분의 내부 로직은 다음과 같다.

 

<!-- problem.ejs -->

<% function renderComments(commentContent, comGroup=0, depth=0) { %>
            <% for (let i=0; i < posts.commentContent.length; i++) { %>
                <% if (commentContent[i].com_group==comGroup) { %>
                    <div class="comment reply" id="comment-<%= posts.commentContent[i].com_idx %>" tabindex="0">

                        <span class="author">
                            <li> 
                                <%= commentContent[i].usr_id %>
                     
                                <!-- Reply button -->
                                <button type="button" class="comment-action-btn" onclick="toggleReplyForm(this, '<%= commentContent[i].com_idx %>')">Reply</button>

                                <!-- Edit button -->
                                <% if (posts.currentUsrId==commentContent[i].usr_id) { %>
                                    <button type="button" class="comment-action-btn" onclick="toggleEditForm(this, '<%= commentContent[i].com_idx %>')">Edit</button>
                                <% } %>

                                <!-- Delete button -->
                                <% if (posts.currentUsrClass==1 || posts.currentUsrId==commentContent[i].usr_id) { %>
                                    <button type="button" id="deleteCommentBtn" class="comment-action-btn" onclick="if(confirm('Are you sure you want to delete this?')){toggleDeleteForm('<%= commentContent[i].com_idx %>')}">Delete</button>
                                <% } %>
                               
                            </li>
                        </span>

                        <p>
                            <%= commentContent[i].text %>
                        </p>

                        <span class="time">
                            <%= new Date(commentContent[i].com_time).toLocaleDateString('ko-KR', { year: 'numeric' , month: 'long' , day: 'numeric' }) %>
                            <%= new Date(commentContent[i].com_time).toLocaleTimeString('ko-KR', { hour: '2-digit' , minute: '2-digit' }) %>
                        </span>

                        <!-- Reply form (initially hidden) -->
                        <div class="reply-form-container" style="display:none;"
                            id="reply-form-<%= posts.commentContent[i].com_idx %>">
                            <form method="post" action="./problem/comment" class="reply-form">
                                <input type="hidden" name="com_idx" value="<%= commentContent[i].com_idx %>">
                                <input type="hidden" name="pro_idx" value="<%= commentContent[i].pro_idx %>">
                                <input type="hidden" name="depth" value="<%= posts.commentContent[i].depth + 1 %>">
                                <input type="hidden" name="usr_idx" value="<%= posts.currentUsrIdx.usr_idx %>">
                                <input type="text" name="comment" placeholder="Enter your reply...">
                                <button type="submit">Reply</button>
                            </form>
                        </div>

                        <!-- Edit form (initially hidden) -->
                        <div class="edit-form-container" style="display:none;"
                            id="edit-form-<%= posts.commentContent[i].com_idx %>">
                            <form method="post" action="./problem/comment/edit" class="edit-form">
                                <input type="hidden" name="comIdx" value="<%= commentContent[i].com_idx %>">
                                <input type="text" name="editText" value="<%= commentContent[i].text %>">
                                <button type="submit">Edit</button>
                            </form>
                        </div>

                        <% renderComments(commentContent, commentContent[i].com_idx, depth + 1); %>
                    </div>
                <% } %>
            <% } %>
        <% } %> 
        <% if (posts.countComment > 0) { %> 
            <div class="content">
                <div class="comments-list">
                    <% renderComments(posts.commentContent, 0, 0); %>
                </div>
            </div>
        <% } %>

 

problem 페이지의 일부 ejs 코드이다. 컨트롤러 파일에선 comments 테이블에 관한 정보를 ejs 파일로 넘겨주는데

ejs 파일의 renderComments 함수는 이 정보를 받아 재귀적으로 함수를 실행시키게 되며 

 

com_group와 depth로 댓글을 DB 내에서 검색해서 이를 반환한다.

 

 

따라서 위 형식으로 댓글이 구성되게 된다.

'Dev' 카테고리의 다른 글

Dockerfile 생성하기  (0) 2025.02.27
비밀번호 초기화 이메일 보내기 구현  (0) 2025.02.27
파일 업로드, 다운로드 기능 추가  (0) 2025.02.27
로그인 기능 구현  (0) 2025.02.27
node.js 회원가입 로직 구현  (0) 2025.02.27