웹 페이지에서 댓글 삭제.

하쮸·2024년 12월 9일
0

1. 개요.

  • 댓글 삭제 기능.
    • 삭제 버튼 추가.
    • 버튼 클릭시 REST API 요청 보내기.
      • 버튼 클릭시 이벤트를 처리할 때 버튼을 통해 댓글의 id값을 전달해야함.

2. 삭제 버튼 추가.

  • 수정 버튼 옆에 추가.

_list.mustache

{{#commentDtos}}
<div class="card m-2" id="comments-{{id}}">
    <div class="card-header">
        {{nickname}}
        <!-- Button trigger modal (댓글 수정 모달 트리거 버튼) -->
        <button type="button" class="btn btn-sm btn-outline-success"
                data-bs-toggle="modal"
                data-bs-target="#comment-edit-modal"
                data-bs-id="{{id}}"
                data-bs-nickname="{{nickname}}"
                data-bs-body="{{body}}"
                data-bs-article-id="{{articleId}}">수정</button>
        <button type="button" class="btn btn-sm btn-outline-danger comment-delete-btn">삭제</button>
    </div>
    <div class="card-body">
        {{body}}
    </div>
</div>
{{/commentDtos}}
  • class 속성 값으로 comment-delete-btn을 추가.
    • 삭제 시 클릭 이벤트 처리를 위한 선택자로 사용.
  • 클래스 선택자는 class 속성 값을 이용해 선택자지정하는 방법으로 마침표(.)기호를 붙여서 사용.
    • 이전에는 아이디 선택자(#id)를 이용해서 HTML 문서의 요소를 선택했음.


3. 자바스크립트로 댓글 삭제.

  • 먼저 삭제 버튼의 클릭 이벤트를 감지해야함.

_list.mustache

<!--  모달 이벤트 처리  -->
<script>
		(생략)
</script>

<!--  댓글 삭제  -->
<script>
    {
        // 삭제 버튼 선택.
        const commentDeleteBtn = document.querySelector(".comment-delete-btn");
        // 삭제 버튼 이벤트 처리.
        commentDeleteBtn.addEventListener("click", function () {
            console.log("삭제 버튼이 클릭됐음.");
        });
    }
</script>
  • document.querySelector()argument클래스 선택자(comment-delete-btn)을 입력해서 삭제 버튼을 선택한 뒤 변수에 저장.
  • addEventListener()로 삭제 버튼의 클릭 이벤트를 감지함.

  • 현재 문제점이 있음.
    • 첫 번째 댓글의 삭제 버튼 클릭시 로그에 숫자가 올라감(or 클릭한 횟수만큼 로그문 출력)
    • 2, 3번 째 댓글의 삭제버튼을 클릭하면 아무런 반응이 없는 상태.

  • 이런 문제발생하는 이유.
    • querySelector()메서드로 삭제 버튼을 선택하면 해당 문서에서 제일 처음에 나온 삭제 버튼만 선택해서 그럼.

3-1. querySelectorAll()

  • 문제 해결방안
    • querySelectorAll()메서드를 사용해야됨.
    • querySelectorAll()메서드는 선택자로 지정한 모든 요소를 찾아서 반환함.
      • 즉, 해당 문서에 있는 모든 삭제 버튼을 선택할 수 있음.

형식

.querySelectorAll("CSS 선택자 문법")

수정된 코드

<!--  댓글 삭제  -->
<script>
    {
        // 삭제 버튼 선택.
        const commentDeleteBtns = document.querySelectorAll(".comment-delete-btn");
    }
</script>

3-2. forEach()

  • 버튼 여러 개를 가져와서 변수화 했으므로 이벤트 처리 코드도 변경되어야 함.
    • 반복 처리를 위해 forEach()메서드를 사용.
      • forEach()메서드
        • 배열 or 배열과 유사한 일련의 데이터 묶음(NodeList, Map, Set, String, ...)을 순회하면서 처리함.
        • 매개변수로 주어진 함수를 배열 속 각 요소에 적용해서 처리함.

형식

.forEach(function () {
	(실행문)
});
<!--  댓글 삭제  -->
<script>
    {
        // 삭제 버튼 선택.
        const commentDeleteBtns = document.querySelectorAll(".comment-delete-btn");
        commentDeleteBtns.forEach(btn => {              // 삭제 버튼 수만큼 반복.
            btn.addEventListener("click", () => {       // 각 버튼의 이벤트 처리.
                console.log("삭제 버튼이 클릭됐음.");
            });
        });
    }
</script>
  • forEach()메서드로 commentDeleteBtns에서 버튼을 하나씩 꺼내 반복함.
  • 각 버튼은 btn이라는 매개변수로 받아 화살표(=>) 함수를 실행시킴.
  • btn 변수로 받아온 버튼에 클릭이벤트가 발생하는 지 감지.

  • 어떤 버튼을 클릭해도 잘 출력되는 것을 확인할 수 있음.

3-3. 삭제 버튼을 클릭 시 해당 댓글의 id 가져오기.

  • 삭제 버튼의 데이터 속성으로 data-comment-id="{{id}}"를 추가.
    • 데이터 속성data-로 시작하고 해당 요소추가 정보를 저장할 때 사용.
<!--  댓글 삭제 버튼  -->
<button type="button"
    class="btn btn-sm btn-outline-danger comment-delete-btn"
    data-comment-id="{{id}}">삭제
</button>
<!--  댓글 삭제  -->
<script>
    {
        // 삭제 버튼 선택.
        const commentDeleteBtns = document.querySelectorAll(".comment-delete-btn");
        commentDeleteBtns.forEach(btn => {              // 삭제 버튼 수만큼 반복.
            btn.addEventListener("click", (event) => {                              // event 객체 받아오기.
                const commentDeleteBtn = event.target;                              // 삭제 버튼 변수화.
                const commentId = commentDeleteBtn.getAttribute("data-comment-id"); // id 가져오기
                console.log(`삭제 버튼 클릭 : ${commentId}번 댓글`);
            })
        });
    }
</script>
  • btn에 클릭 이벤트가 발생했을 때 이벤트와 관련한 버튼 요소를 가져옴.
    • 화살표 함수(=>)매개변수로 event 객체를 받아옴.
    • event.target으로 이벤트를 발생시킨 요소, 즉 삭제버튼을 가져와서 변수에 저장.
    • data-comment-id 속성 값을 가져와서 변수에 저장.
      • data-comment-id는 삭제 버튼의 데이터 속성으로 댓글의 id를 저장하고 있음.

  • 콘솔 로그에 몇 번 댓글의 삭제 요청이 있었는 지 확인할 수 있음.

3-4. 자바스크립트로 REST API 호출, 응답

// 삭제 댓글 id 가져오기.
const commentId = commentDeleteBtn.getAttribute("data-comment-id"); // id 가져오기
console.log(`삭제 버튼 클릭 : ${commentId}번 댓글`);

// 삭제 REST API 호출.
const url = `/api/comments/${commentId}`;
fetch(url, {
    method: "DELETE"
}).then(response => {
    // 댓글 삭제 실패.
    if (!response.ok) {
        alert("댓글 삭제 실패!");
        return;
    }
    // 댓글 삭제 성공
    const msg = `${commentId}번 댓글을 삭제했음.`;
    alert(msg);
    window.location.reload();
})
  • url 변수에 댓글 삭제 API 주소를 저장.
    • 백틱(`)을 이용해서 좀 더 편리하고 직관적인 코드가 됨.
  • fetch() 함수 작성.
    • 첫 번째 전달값으로 API 주소를 가지고 있는 url넘김.
    • 두 번째 전달값으로 요청 메서드를 넘김.
      • 생성, 수정할 때 처럼 전송 본문(body)이 있는 것이 아니므로 headers, body속성을 없어도 됨.

4. (참고) 화살표 함수.

  • 화살표 함수는 function 키워드 대신 화살표(=>)를 사용해서 함수를 정의하는 방법.
  • 아래의 두 코드는 같은 의미임.
btn.addEventListener("click", () => {...})			
btn.addEventListener("click", function() {...})
  • 매개변수의 개수에 따라 화살표 함수의 사용형식.
() => {...}						// 매개변수가 없는 경우.
x => {...} or (x) => {...}		// 매개변수가 1개인 경우.
(x, y) => {...}					// 매개변수가 여러 개인 경우.

5. (참고) 백틱.

  • 백틱(`)은 문자열을 정의하는 방법.
  • 백틱(`)을 사용하면 ${} 문법으로 문자열에 변수 or 식을 넣을 수 있어서 편리함.

형식

`삭제 버튼 클릭: ${commentId}번 댓글`		// 백틱(`) 문자열에 변수 삽입.
"삭제 버튼 클릭: " + commentId + "번 댓글"	// 큰따옴표 문자열을 덧셈으로 연결.
profile
Every cloud has a silver lining.

0개의 댓글