_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 문서의 요소를 선택했음.
_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()로 삭제 버튼의 클릭 이벤트를 감지함.
삭제버튼을 클릭하면 아무런 반응이 없는 상태.
문제가 발생하는 이유.querySelector()메서드로 삭제 버튼을 선택하면 해당 문서에서 제일 처음에 나온 삭제 버튼만 선택해서 그럼.문제 해결방안querySelectorAll()메서드를 사용해야됨.querySelectorAll()메서드는 선택자로 지정한 모든 요소를 찾아서 반환함.형식
.querySelectorAll("CSS 선택자 문법")
수정된 코드
<!-- 댓글 삭제 -->
<script>
{
// 삭제 버튼 선택.
const commentDeleteBtns = document.querySelectorAll(".comment-delete-btn");
}
</script>
forEach()메서드를 사용.forEach()메서드형식
.forEach(function () {
(실행문)
});
<!-- 댓글 삭제 -->
<script>
{
// 삭제 버튼 선택.
const commentDeleteBtns = document.querySelectorAll(".comment-delete-btn");
commentDeleteBtns.forEach(btn => { // 삭제 버튼 수만큼 반복.
btn.addEventListener("click", () => { // 각 버튼의 이벤트 처리.
console.log("삭제 버튼이 클릭됐음.");
});
});
}
</script>
forEach()메서드로 commentDeleteBtns에서 버튼을 하나씩 꺼내 반복함.btn이라는 매개변수로 받아 화살표(=>) 함수를 실행시킴.
데이터 속성으로 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>
이벤트가 발생했을 때 이벤트와 관련한 버튼 요소를 가져옴.화살표 함수(=>)의 매개변수로 event 객체를 받아옴.event.target으로 이벤트를 발생시킨 요소, 즉 삭제버튼을 가져와서 변수에 저장.data-comment-id 속성 값을 가져와서 변수에 저장.data-comment-id는 삭제 버튼의 데이터 속성으로 댓글의 id를 저장하고 있음.
// 삭제 댓글 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();
})
API 주소를 저장.첫 번째 전달값으로 API 주소를 가지고 있는 url넘김.두 번째 전달값으로 요청 메서드를 넘김.전송 본문(body)이 있는 것이 아니므로 headers, body속성을 없어도 됨.btn.addEventListener("click", () => {...})
btn.addEventListener("click", function() {...})
() => {...} // 매개변수가 없는 경우.
x => {...} or (x) => {...} // 매개변수가 1개인 경우.
(x, y) => {...} // 매개변수가 여러 개인 경우.
형식
`삭제 버튼 클릭: ${commentId}번 댓글` // 백틱(`) 문자열에 변수 삽입.
"삭제 버튼 클릭: " + commentId + "번 댓글" // 큰따옴표 문자열을 덧셈으로 연결.