BE/스프링 부트 3

18장 웹 페이지에서 댓글 수정하기

이제하네 2024. 1. 4. 12:00

댓글 수정 뷰 페이지 만들기

  • 수정 버튼과 모달 추가하기
    1. _list.mustache 파일에 {{nickname}} 다음행에 <button> 태그 넣기
    2. 부트스트랩 페이지에서 modal 를 검색해서 Modal components를 찾은후 Live demo 찾고 <!-- Button trigger modal--> 부분을 복사
    3. _list.mustache 파일
      1. 복사한 코드를 {{nickname}} 아래에 붙여 넣고 줄정리 하기
      2. 버튼 제목을 변경
        • data-bs-toggle="modal" : 클릭하면 모달이 나타나고 다시 클릭하면 사라짐 (토글 역활)
        • data-bs-target="#exampleModal": 해당 id의 모달이 실행
    4. 부트스트랩에서  <!-- Modal -->  부분도 복사하고 _list.mustache 코드의 맨 아래 붙여 넣은후 줄 정리 하기
    5. <!-- Modal --> 부분의 코드 수정
      1. 모달의 id 를 comment-edit-modal로 변경 . 모달의 id를 수정했으므로 모달 트리거 버튼의 data-bs-target 속성값도 같이 변경
      2. 모달에 필요 없는 속성 삭제
      3. 모달 제목을 변경
      4. [Close] , [Save changes] 버튼은 필요 없으므로 modal-footer 영역 삭제
_list.mustache
		
        <중략>
        
		<!-- 댓글 헤더 영역 설정  -->
		<div class="card-header">
			{{nickname}} <!--닉네임 보여주기  -->
			<!-- Button trigger modal --> 
			<button type="button"
            	class="btn btn-sm btn-outline-primary"
            	data-bs-toggle="modal"
            	  data-bs-target="#comment-edit-modal">수정</button>  
		</div>
        
       <중략> 

<!-- Modal -->
<div class="modal fade" id="comment-edit-modal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title" 
                    id="exampleModalLabel">댓글 수정</h1>
                <button type="button" 
                        class="btn-close" 
                        data-bs-dismiss="modal" 
                        aria-label="Close"></button>
            </div>
            <div class="modal-body">
                
            </div>
        </div>
    </div>
</div>

모달창 생성

 

  • 수정 폼 삽입하기
    1. _new.mustache 파일로가서 상단의 <form> 태그 안에 코드를 복사
    2. _list.mustache 파일로가서 모달 본분에 복사한 코드 붙여 넣기
    3. 붙여 넣은 코드 수정
      1. <form> 태그 위에 <!--댓글 수정 폼-->주석 추가
      2. 닉네임 input 박스의 id를 edit-comment-nickname으로 수정
      3. 댓글 본문 textarea 박스의 id를 edit-comment-body로 수정
      4. 히든 인풋의 머스테치 변수 삭제
      5. <input> 에 value 속성은 필요 없으므로 삭제하고 id를 edit-comment-id(댓글의 id)로 수정하고 <input> 을 복사해서 하나더 붙여 넣고 id를 edit-comment-article-id(부모 게시글의 id)로 수정
      6. 전송 버튼의 id를 comment-update-btn 으로 수정하고 버튼 제목 변경
_list.mustache 에 있는 모달 본문

 			<div class="modal-body">
                 <!-- 댓글 수정 폼 -->  
        		<form> 
        			<!--닉네임 입력   -->
            		<div class="mb-3"> 
            			<label class="form-label">닉네임</label>
            			<input type="text" class="form-control" id="edit-comment-nickname">
            		</div>
            		<!--댓글 본문 입력  -->
            		<div class="mb-3"> 
            			<label class="form-label">댓글 내용</label>
            			<textarea class="form-control" rows="3" id="edit-comment-body"></textarea>
            			<!-- 히든 인풋  -->
            			<input type="hidden" id="edit-comment-id">
            			<input type="hidden" id="edit-comment-article-id">
            		</div>
            		<!--전송 버튼  -->
           			<button type="button" class="btn btn-primary" id="comment-update-btn">수정 완료</button>
        			</form>
            </div>

모달 본문에 <form> 태그 작성

 

자바스크립트로 댓글 수정하기

  • 트리거 데이터 전달하기
    1. _list.mustache 파일에서 댓글은 {{#commentDtos}}…{{/commentDtos}} 머스테치 문법으로 감싸져 있어서 이 구문을 이용해 commentDto에 저장된 데이터를 몸달 트리거 버튼의 속성값으로 가져옴ㅁ
      1. data-bs-id 속성을 추가하고 현재 댓글의 {{id}} 값을 저장
      2. data-bs-nickname 속성을 추가하고 현재 댓글의 {{nickname}} 값을 저장
      3. data-bs-body속성을 추가하고 현재 댓글의 {{ body }} 값을 저장
      4. data-bs-article-id속성을 추가하고 현재 댓글의 {{articleId}} 값을 저장
        • data-시작하는 속성을 데이터 속성이라함
        • 데이터 속성은 HTML 요소에 추가 정보를 저장하고 싶을때 사용
        • 개수에 제한이 없으므로 하나의 요소에 여러 데이터 속성 사용 가능
    2. 받아온 데이터를 모달의 각 폼에 출력하기위해 코드 맨 아래에 <script> 태그 작성후 그 사이를 중괄호({})로 영역을 잡음
    3. 모달 이벤트를 처리하기 위해 모달을 선택하기 위해 querySelector()메서드로 모달을 선택하고 commentEditModal 변수에 저장
    4. 모달이 열리는 이벤트가 발생하면 기존 댓글을 받아옴
      • 이벤트 타입 설명
        show.bs.modal 모달이 표시되기 직전 실행되는 이벤트
        shown.bs.modal 모달이 표시된 후 실행되는 이벤트
        hide.bs.modal 모달이 숨겨지기 직전 실행되는 이벤트
        hidden.bs.modal 모달이 숨겨진 후 실행되는 이벤트
      •  function(event): 이벤트를 받아 처리하는 함수 , 즉 이벤트 핸들러
      • function() 안에 있는 event 는 발생된 이벤트 정보를 가리키는 매개변수 여기서는 show.bs.modal을 가리킴
    5. fuction(event) 함수 내부 구현하기
      1. 트리거 버튼 선택
        • 모달 트리거 버튼은 매개 변수로 받은 event의 relatedTarget 으로 선택하고 triggerBtn 변수에 저장
      2. 데이터 가져오기
        • 모달 트리거 버튼의 속성값으로 있는 것들을 triggerBtn 변수를 통해 가져오기
      3. 가져온 데이터를 모달의 각 폼에 반영
        • querySelector을 통해 닉네임 입력 폼을 선택하고 해당 요소의 value 속성에 데이터 저장
_list.mustache

<!-- Button trigger modal --> 
			<button type="button"
            		class="btn btn-sm btn-outline-primary"
            		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>  
		</div>


<script>
{
	//모달 요소 선택
	const commentEditModal = document.querySelector("#comment-edit-modal");
	//모달 이벤트 감지
	commentEditModal.addEventListener("show.bs.modal", function(event) {
		// 1. 트리거 버튼 선택
		const triggerBtn = event.relatedTarget;
		// 2. 데이터 가져오기
		const id = triggerBtn.getAttribute("data-bs-id");                 //id 가져오기
		const nickname = triggerBtn.getAttribute("data-bs-nickname");     //닉네임 가져오기
		const body = triggerBtn.getAttribute("data-bs-body");             //본문 가져오기
		const articleId = triggerBtn.getAttribute("data-bs-article-id");  //부모 id 가져오기
		// 3. 수정 폼에 데이터 반영
		document.querySelector("#edit-comment-nickname").value = nickname;    //닉네임 반영
		document.querySelector("#edit-comment-body").value = body;            //댓글 본문 반영
		document.querySelector("#edit-comment-id").value = id;                //id 반영
		document.querySelector("#edit-comment-article-id").value = articleId; // 부모 id 반영
	});
}
</script>

수정 전 데이터 잘 가져옴

 

  • 자바스크립트로 REST API 호출하고 응답 처리하기
    1. <script>태그 안에 또다른 중괄호({})블록을 잡고 수정 완료 버튼을 선택
    2. 수정 완료 버튼에 클릭 이벤트가 발생하는지 감지하고 있다가 이벤트가 발생하면 함수를 실행하도록 addEventListener()를 작성
    3. 댓글을 수정하기 위해 먼저 객체를 생성
      1. 객체 리터럴 방식으로 생성
    4. REST API를 호출해 수정 내용을 DB에 반영하기위해 url 이라는 상수 타입의 변수를 만들고 댓글 수정 API 주소를 저장
    5. fetch()함수 작성
      1. 첫번째 전달값으로 API 주소를 가지고 있는 url 을 넘김
      2. 두번째 전달값으로 요청 메서드, 헤더 정보, 전송 본문을 넘김 , 전송 데이터에는 comment 객체를 JSON 형태로 변환해 전달하기 위해 JSON.stringify() 메서드 사
    6. 사용자가 댓글 수정이 잘 됐는지 안됐는지 확인 할수 있도록 fetch().then(response => { 응답 처리문 }) 구문을 이
_list.mustache

{
	// 수정 완료 버튼 선택
	const commentUpdateBtn = document.querySelector("#comment-update-btn");
	// 클릭 이벤트 처리
	commentUpdateBtn.addEventListener("click" , function(){
		const comment = { //객체 변수 선언
			id: document.querySelector("#edit-comment-id").value,
			nickname: document.querySelector("#edit-comment-nickname").value,
			body: document.querySelector("#edit-comment-body").value,	
			article_id: document.querySelector("#edit-comment-article-id").value
			};
		console.log(comment);
		// 수정 REST API 호출
		const url = "/api/comments/" + comment.id;
		fetch(url, {
			  method: "PATCH", // PATCH 요청
			  headers: {       // 전송 데이터 타입(JSON) 정보
			    "Content-Type": "application/json"
			  },
			  body: JSON.stringify(comment) //comment 객체를 JSON 문자열로 변환 전송
			}).then(response => {
				  // HTTP 응답 코드에 따른 메시지 출력
				  const msg = (response.ok) ? "댓글이 수정됐습니다." : "댓글 수정 실패..!";
				  alert(msg);
				  // 현재 페이지 새로 고침
				  window.location.reload();
			});
	});
}

댓글 수정 완료