BE/스프링 부트 3

17장 웹 페이지에서 댓글 등록하기

이제하네 2024. 1. 2. 20:17

댓글 생성 뷰 페이지 만들기

  1. 부트스트랩 홈페이지에서 card 로 검색해 Body 스타일을 찾은후 코드를 복사
  2. _new.mustahce 파일에 복사한 코드를 붙혀 넣기
    1. <div> 태그에 class 속성을 card m-2로 수정하고 id는 comments-new 추가
    2. 카드 본문에 적혀 있는 텍스트 삭제
  3. 댓글 작성 폼은 부트스트랩에 form으로 검색후 OverView 스타일을 찾은후 코드를 복사
  4. 복사한 코드를 카드 본문 영역에 붙여 넣고 다음과 같이 설정
    1. 맨위에 댓글 작성 폼이라는 주석을 추가
    2. <div> 태그중 세번째는 필요 없으므로 삭제
  5. 나머지 코드는 다음과 같이 수정하고 각 요소의 id도 이해하기 쉽게 변경
    1. 첫번째 <div> 태그는 닉네임 입력 폼으로 작성하기 위해 label의 요소의 for="exampleInputEmail1" 속성을 지우고 제목을 수정 그리고 닉네임은 텍스트 임므로 <input> 요소의 속성을 type="text", id = "new-comment-ninckname"으로 수정 후  aria-describedby="emailHelp" 속성은 삭제하고 마지막 <div>태그는 삭제
    2. 두번째 <div> 태그는 댓글 본문 입력 폼으로 작성하기 위해 label의 요소의 for="exampleInputEmail1" 속성을 지우고 제목을 수정 그리고 댓글 본문 내용이 많으므로 <input> 대신 여러줄 입력할수있는 <textarea> 태그로 수정하고 속성은 type="text" , rows="3", id="new-comment-body" 로 설정
    3. 댓글은 부모 게시글의 id 값을 가지고 있어야 하기에 히든 인풋으로  type="hidden", id="new-comment-article-id", value="{{id}}"로 설정 
      • 히든 인풋 : 사용자가 입력하거나 선택하는 정보는 아니지만 폼 전송이 같이 전송해줘야 하는 정보를 담기 위해 필요한것으로 화면에 출력되는 부분이 아니기 때문에 폼의 외형을 제작할때는 아무런 영향을 미치지않음
    4. 마지막으로 전송 버튼을 생성하기위해 요소의 속성을 type="button", id="comment-create-btn" 으로 설정 
_new.mustache

<div class="card m-2" id="comments-new"> <!-- class 속성 수정, id 속성 추가 -->
    <div class="card-body">
    	 <!-- 댓글 작성 폼 -->  <!-- 주석 추가 -->
        <form> 
            <div class="mb-3"> <!--닉네임 입력 폼 만들기  -->
            	<label class="form-label">닉네임</label>
            	<input type="text" class="form-control" id="new-comment-nickname">
            </div>
            <div class="mb-3"> <!--댓글 본문 입력 폼 만들기  -->
            	<label class="form-label">댓글 내용</label>
            	<textarea class="form-control" rows="3" id="new-comment-body"></textarea>
            	<!-- 히든 인풋  -->
            	{{#article}}
            		<input type="hidden" id="new-comment-article-id" value="{{id}}">
            	{{/article}}
            </div>
            <!--전송 버튼  -->
           <button type="button" class="btn btn-primary" id="comment-create-btn">Submit</button>
           <!-- 전송 버튼 만들기  -->
        </form>
    </div>
</div>

댓글 작성 화면

 

자바스크립트로 댓글 달기

  1. 버튼 클릭 이벤트 감지하기 
    1. _new.mustache 코드 맨 아래에 <script> 태그를 작성하고 안쪽을 블록({})으로 잡음
    2. querySelector()메서드를 사용해 버튼의 클릭하면 버튼을 상수(const) 타입의 commentCreateBtn 변수에 저장
      • querySelector()메서드는 웹 페이지에서 해당 id값을 가진 요소를 찾아 변수에 저장
      • 형식 : 자료형 변수명 = document.querySelector("#id_값");
    3. 버튼이 클릭 되는지 감지하기위해 addEventListener()메서드를 사용
      • addEventListener()메서드는 HTML 문서의 트겅 요소가 이벤트를 감지
      • 형식 : 요소명.addEventListener("이벤트_타입", 이벤트_처리_함수) 
  2. 새 댓글 자바스크립트 객체 생성하기
    1. 자바스크립트에서 객체를 만드는 방법은 3가지가 있는데 여기서는 닉네임과 댓글 본문을 객체 리터럴 방식으로 생성
      1. 객체 리터럴 방식 
        • 객체를 변수로 선언해 사용하는 방식
        • 형식 :
          var object = {
            key1: value1,
            key2: value2,
            ...
          }
      2. 생성자 함수 방식
        • 객체를 생성하는 방식
        • 형식 :
          const Person = function(firstName, birthYear) { 
          	this.firstName = firstName; 
          	this.birthYear = birthYear; 
          }; 
          const name = new Person('Kim', 2023); 
          console.log(name);
      3. Object.create() 방식
        • 지정된 프로토타입 객체 및 속성(property)을 갖는 새 객체를 만드는 방식
        • 형식 : Object.create(부모객체.prototype)
  3. 자바스크립트로 REST API 호출하고 응답 처리하기 
    1. url 이라는 상수(const) 타입의 변수를 만들고 댓글 생성 API 주소를 저장하고 부모 게시글의 id는 매번 바뀌므로 comment.articleId로 작성하고 앞뒤 주소와 연결
    2. fetch()함수 작성
      • fetch()함수는 웹 페이지에서 HTTP 통신 하는데 사용
      • 형식:
        fetch('API_주소', {
          method: 'POST',             // 요청 메서드(GET, POST, PATCH, DELETE)
          headers: {                  // 헤더 정보
            "Content-Type": "application/json"  
          },
          body: JSON.stringify(객체)  // 전송 데이터
        }).then(response => {        // 응답을 받아 처리하는 구문
          응답_처리문; 
        });​
    3. 댓글이 등록됐습니다 라는 메시지를 나오게 하기위해 fetch()함수의 응답 처리 구문으로 구현 
    4.  
_new.mustache 맨 아래에 추가

<script>
{
	//댓글 생성 버튼 변수화
	const commentCreateBtn = document.querySelector("#comment-create-btn");
	
	//댓글 클릭 이벤트 감지
	commentCreateBtn.addEventListener("click", function() { 
		console.log("버튼을 클릭");
		const comment = {
			// 새 댓글의 닉네임
			nickname: document.querySelector(" #new-comment-nickname").value,
			// 새 댓글의 본문
			body: document.querySelector(" #new-comment-body").value,
			// 부모 게시글의 id
			articleId: document.querySelector(" #new-comment-article-id").value
		}
		 console.log(comment);
		// fetch() - 비동기 통신을 위한 API
		const url = "/api/articles/" + comment.articleId + "/comments";
	
		fetch(url, {                        // fetch() 함수 작성
		  	method: "POST",               // POST 요청 
		  	headers: {                    // 전송 본문의 데이터 타입(JSON) 정보
		    	"Content-Type": "application/json"
		  	},
		 	 body: JSON.stringify(comment) // comment 객체를 JSON 문자열로 변환해 전송
		}).then(response => {
		  	// HTTP 응답 코드에 따른 메시지 출력
		  	const msg = (response.ok) ? "댓글이 등록됐습니다." : "댓글 등록 실패..!";
		  	alert(msg); 
		  	// 현재 페이지 새로 고침
			  window.location.reload();                                     
		});
	});
}
</script>

 

댓글 생성 성공