1.  댓글 등록

댓글 추가는 모달창을 이용해서 처리
  ⚡️  모달창을 이용해서 새로운 댓글이 필요한 replyText나 replyWriter를 입력하도록 구성하고, 자바스크립트의 객체로 POST 호출하도록 구성

reply.js에 새로운 댓글을 등록하는 기능을 추가


  📍 파라미터를 JS의 객체로 받아서 axios.post()를 이용해서 전달해 줌

async function addReply(replyObj) {
    const response = await axios.post(`/api/replies/`, replyObj);
    return response;
}

 

  ✓  addReply()가 정상적으로 처리되면 서버에서는 '{'rno':11}'과 같은 JSON 데이터를 전송하게 됨
  ✓  이를 이용해서 댓글이 추가되면 경고창을 보여주고 마지막 페이지로 이동해서 등록된 댓글을 볼 수 있게 구성

 

read.html에는 댓글 등록을 위한 모달창을 <div layout:fragment="content">가 끝나기 전에 추가
<!-- register modal -->
<div class="modal registerModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Register Reply</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            
            <div class="modal-body">
                <div class="input-group mb-3">
                    <span class="input-group-text">Reply Text</span>
                    <input type="text" class="form-control replyText" >
                </div>
                <div class="input-group mb-3">
                    <span class="input-group-text">Reply Writer</span>
                    <input type="text" class="form-control replyWriter" >
                </div>
            </div>
        
            <div class="modal-footer">
                <button type="button" class="btn btn-primary registerBtn">Register</button>
                <button type="button" class="btn btn-outline-dark closeRegisterBtn" >Close</button>
            </div>
        </div>
    </div>
</div>
<!-- // register modal -->

 

  ✓  모달창의 class 속성값은 registerModal이라고 지정하고 <input> 태그들은 replyText와 replyWriter 속성값을 지정
  ✓  모달창의 버튼들도 구분하기 위해서 class 속성값을 registerBtn, closeRegisterBtn 등으로 지정해서 사용

 

read.html의 <script> 부분에는 자주 사용하는 DOM 객체들을 미리 변수로 처리
// 등록 작업 관련
const registerModal = new bootstrap.Modal(document.querySelector('.registerModal'));

const registerBtn = document.querySelector('.registerBtn');
const replyText = document.querySelector('.replyText');
const replyWriter = document.querySelector('.replyWriter');
const closeRegisterBtn = document.querySelector('.closeRegisterBtn');

 

ADD REPLY 버튼을 눌렀을 때 모달창을 보여주도록 이벤트 처리와 모달창의 Close 버튼에 대한 처리
document.querySelector('.addReplyBtn').addEventListener('click', function (e) {
    registerModal.show();
});

closeRegisterBtn.addEventListener('click', function (e) {
    registerModal.hide();
});

 

모달창 오른쪽 하단의 Register 버튼을 눌렀을 때 이벤트 처리를 추가

 

  📍  reply.js의 addReply()를 호출하고 경고창을 통해서 추가된 댓글의 번호를 보여줌
  📍  경고창이 닫히면 마지막 페이지를 다시 호출해서 등록된 댓글이 화면에 보일 수 있도록 구성

registerBtn.addEventListener('click', function (e) {
    // 매개변수로 사용할 객체 생성
    const replyObj = { bno: bno, replyText: replyText.value, replyWriter: replyWriter.value }
    addReply(replyObj).then(result => { // 등록이 된 후 결과처리
        alert(result.data.rno);
        registerModal.hide();
        replyText.value = '';
        replyWriter.value = '';
        printReplies(1, 10, true); // 댓글 목록 갱신
    }).catch(e => {
        alert('Exception');
    });
});


2.  댓글 페이지 번호 클릭

새로운 댓글이 추가되면 자동으로 마지막 페이지로 이동하기는 하지만, 댓글의 페이지 번호를 누를 때도 이동할 수 있으므로 수정 / 삭제 전에 페이지 이동 처리는 먼저 진행
  ⚡️  화면에서 페이지 번호를 구성하는 부분은 <li> 태그 내에 존재하는 <a> 태그이고 페이지 번호가 'data-page' 속성값으로 지정되어 있음

  ⚡️  페이지 번호는 매번 새로이 구성하므로 이벤트 처리할 때는 항상 고정되어 있는 <ul>을 대상으로 이벤트 리스너를 등록하는 방식을 이용

 

read.html에 코드 추가
// 3. 페이징 클릭
let page = 1;
let size = 10;

replyPaging.addEventListener('click', function (e) {
    e.preventDefault();
    e.stopPropagation();

    const target = e.target;
    if (!target || target.tagName !== 'A') {
        return;
    }

    page = target.getAttribute('data-page');
    printReplies(page, size);
});

 

  ✓  page와 size를 별도의 변수로 처리하는 것은 나중에 댓글 수정과 같은 작업에서 현재 페이지 번호를 유지 해야 할 가능성이 있기 때문
  ✓  이벤트 처리가 완료되면 댓글의 페이지 이동이 가능해 짐

 


3.  댓글 조회와 수정

댓글을 조회한다는 것은 댓글을 수정하거나 삭제하기 위함
댓글 조회는 등록과 유사하게 모달창을 이용해서 수정이나 삭제가 가능한 버튼들을 보여주는 형태로 구성

 

1)  Axios 통신 부분

  👾  reply.js에는 특정한 번호의 댓글을 조회하고 수정할 수 있는 기능을 구성
  👾  댓글 조회는 GET 방식으로 처리되고, 댓글 수정은 PUT 방식으로 호출

async function getReply(rno) {
    const response = await axios.get(`/api/replies/${rno}`);
    return response.data;
}

async function modifyReply(replyObj) {
    const response = await axios.put(`/api/replies/${replyObj.rno}`, replyObj);
    return response.data;
}

 

2)  read.html의 모달창 처리

  👾  댓글 수정 후에는 다시 현재 페이지를 호출해서 최대한 목록에서 수정된 댓글을 확인할 수 있도록 함

 

read.html에 등록 모달창 아래 영역을 새롭게 추가
<!-- modify modal -->
<div class="modal modifyModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title replyHeader"></h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
        
            <div class="modal-body">
                <div class="input-group mb-3">
                    <span class="input-group-text">Reply Text</span>
                    <input type="text" class="form-control modifyText" >
                </div>
            </div>

            <div class="modal-footer">
                <button type="button" class="btn btn-info modifyBtn">Modify</button>
                <button type="button" class="btn btn-danger removeBtn">Remove</button>
                <button type="button" class="btn btn-outline-dark closeModifyBtn">Close</button>
            </div>
        </div>
    </div>
</div>
<!-- // modify modal -->

 

  ✓  <div class="modifyModal">의 경우 class 속성값이 replyHeader 영역을 이용해서 선택한 댓글의 번호를 보여주도록 하고, modifyText 부분에는 댓글의 내용을 수정할 수 있도록 구성

 

read.html에 변수들을 추가해서 제어가 가능하도록 구성
const modifyModal = new bootstrap.Modal(document.querySelector('.modifyModal'));
const replyHeader = document.querySelector('.replyHeader');
const modifyText = document.querySelector('.modifyText');
const modifyBtn = document.querySelector('.modifyBtn');
const removeBtn = document.querySelector('.removeBtn');
const closeModifyBtn = document.querySelector('.closeModifyBtn');

 

특정한 댓글을 눌렀을 때 모달창을 보여주도록 replyList에 이벤트 처리를 추가

 

  📍  댓글 목록 역시 매번 브라우저에서 새로 만들어지기 때문에 이벤트는 항상 존재하는 바깥쪽 <ul>을 대상으로 처리

// 댓글 내용을 클릭했을 때 수정 모달창 띄우기
replyList.addEventListener('click', function (e) {
    e.preventDefault();
    e.stopPropagation();

    const target = e.target;
    if (!target || target.tagName !== 'SPAN') {
        return;
    }

    const rno = target.getAttribute('data-rno');
    if (!rno) {
        return;
    }
    
    getReply(rno).then(reply => { // 댓글의 내용을 모달창에 채워서 보여줌
        console.log(reply)
        replyHeader.innerHTML = reply.rno;
        modifyText.value = reply.replyText;
        modifyModal.show();
    }).catch(e => alert('error'));
});

 


3)  댓글 수정과 화면 갱신

  👾  댓글 수정은 화면에 있는 댓글의 내용과 번호, 게시물의 번호를 이용해서 처리할 수 있음
  👾  신경써야 할 부분은 댓글의 수정 후 처리.

         ➡️  수정된 댓글은 결국 목록에서 확인하게 되기 때문에 만일 사용자가 댓글을 수정하는 사이에 댓글이 많이 추가되면 확인할 방법이 없음

  👾  최대한 자신이 보고 있었던 페이지를 유지하는 수준으로 구현하도록 함

 

화면에서 Modify 버튼에 대한 이벤트 처리와 Close 버튼의 이벤트 처리를 작성
// 모달창의 수정 버튼 클릭
modifyBtn.addEventListener('click', function (e) {
    console.log('modifyBtn... click');
    const replyObj = {bno: bno, rno: replyHeader.innerHTML, replyText: modifyText.value};

    modifyReply(replyObj).then(result => {// 수정 처리 후
        alert(result.rno + '댓글이 수정되었습니다.');
        modifyText.value = '';
        modifyModal.hide();
        printReplies(page, size);
    }).catch(e => {
    console.log(e)
    });
});

// 모달창 close 버튼 클릭
closeModifyBtn.addEventListener('click', function () {
    modifyModal.hide();
});

 

  ✓  댓글이 수정된 후에는 다시 현재 페이지를 볼 수 있도록 printReplies()를 호출하므로 수정한 후에 현재 페이지를 다시 갱신


4)  댓글 삭제

reply.js에 삭제 처리 추가
async function removeReply(rno) {
    const response = await axios.delete(`/api/replies/${rno}`);
    return response.data;
}

 

read.html에는 모달 창의 Remove 버튼을 눌러서 댓글을 삭제

 

  📍 삭제 후에는 경고창을 통해서 댓글이 삭제되었음을 알려주고 댓글의 1페이지로 이동

/*
5. 삭제 관련
*/
removeBtn.addEventListener('click', function (e) {
    removeReply(replyHeader.innerHTML).then(result => {
        alert(result.rno + ' 댓글이 삭제되었습니다.');
        modifyText.value = '';
        modifyModal.hide();
        page = 1; // 해당 댓글이 삭제되었으니 1페이지로 이동
        printReplies(page, size);
    }).catch(e => {
    console.log(e)
    });
});

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts