웹 페이지에서 댓글 등록.

하쮸·2024년 12월 5일
0

1. 개요.

  • 댓글을 등록하기 위한 페이지를 만들고 자바스크립트코드로 REST API 호출하기.
    • 이를 위해 사용하는 자바스크립트 API
      • document.querySelector()
        • 웹 페이지에서 특정 요소(버튼)을 찾아서 반환.
      • addEventListener()
        • 특정 요소에 이벤트가 발생(버튼 클릭)했을 때 특정 동작(댓글 객체 전달)을 수행 함.
      • fetch()
        • 웹 페이지에서 REST API요청(POST 요청)을 보냄.
  • 페이지 구성.
    • 기존 댓글을 보여주는 영역. (_list)
    • 새 댓글을 입력하는 영역. (_new)
    • 댓글 전체 영역, 즉 뷰(view). (_comments)

2. 댓글 생성 뷰 페이지.

  • 부트스트랩 -> card

_new.mustache

<div class="card m-2" id="comments-new">
    <div class="card-body">
        
    </div>
</div>
  • class="card m-2"
    • card 스타일 적용, 여백(margin)을 2만큼 줌.
  • id="comments-new"
    • 요소를 유일하게 구분하기 위한 id.

댓글 작성 폼

  • 부트스트랩 -> forms

_new.mustache

<div class="card m-2" id="comments-new">
    <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 type="text" class="form-control" rows="3" id="new-comment-body"></textarea>
            </div>
            <!--  히든 인풋  -->
            {{#article}}
                <input type="hidden" id="new-comment-article-id" value="{{id}}">
            {{/article}}
            <!--  전송 버튼  -->
            <button type="button" class="btn btn-primary" id="comment-create-btn">댓글 작성</button>
        </form>
    </div>
</div>
  • 닉네임 입력
    • 닉네임은 텍스트이므로 <input>요소의 속성을 type="text", id="new-comment-nickname".
  • 댓글 본문 입력
    • 댓글 본문에는 내용이 많으므로 <input> 대신 여러 줄을 입력할 수 있는 <textarea></textarea>로 작성.
  • 히든 인풋
    • 댓글은 부모 게시글의 id값을 가지고 있어야 함.
      • 댓글이 게시글에 종속되기 때문.
      • 그래서 이를 위해 부모 게시글의 id를 히든 인풋으로 넣음.
        • 히든 인풋(hidden input)
          • 웹 페이지에 표시되지 않는 요소.
          • 보이지는 않지만 값을 가지고 있어야 할 때 사용함.
    • mustache문법으로 변수의 사용 범위를 지정. ({{#article}}..{{/article}})

  • 하단 댓글 작성버튼을 눌렀을 때 댓글이 입력되도록 자바스크립트로 구현.
    • _new.mustache파일의 코드에서 제일 밑에 작성.

3. 자바스크립트.

  • 웹 페이지에서도 자바스크립트를 사용하면 REST API를 호출할 수 있음.

_new.mustache

<!--  댓글 작성하기  -->
<script>
    {
        // 댓글 생성 버튼 변수화.
        const commentCreateBtn = document.querySelector("#comment-create-btn");
        commentCreateBtn.addEventListener("click", function () {
            console.log("버튼을 클릭했음.");
        });
    }
</script>
  • 자바스크립트의 querySelector()메서드.
    • 웹 페이지에서 특정 요소를 선택할 때 사용함.
    • 메서드에 id, name, class, HTML 태그 등의 값을 입력하면 해당 속성 값을 가진 대상을 반환함.
      • id값으로 대상을 찾을 때는 id 값 앞에 #을 붙임.
      • 이를 아이디 선택자(#id)라고 함.
  • 댓글 작성 버튼의 id값인 comment-create-btn#과 함께 입력하고, 댓글 작성 버튼을 상수(const)타입의 commentCreateBtn변수에 저장.
// 해당 id 값을 가진 요소를 찾아 변수에 저장.
// 형식.
자료형 변수명 = document.querySelector("#id값");
  • addEventListener()메서드.
    • HTML문서의 특정 요소가 이벤트를 감지함.
    • 이벤트발생하면 지정된 함수실행함.
  • 댓글 작성 버튼(commentCreateBtn)을 클릭(click)했을 때 함수(function)를 실행하도록.
// 이벤트가 감지되면 이벤트 처리 함수 실행.
// 형식.
요소명.addEventListener("이벤트 타입", "이벤트 처리 함수)


3-1. 객체 생성.

  • 새로 작성한 닉네임, 댓글 본문을 자바스크립트 객체로 만들어서 출력.
  • 자바스크립트에서 객체를 만드는 3가지 방법.

    • 객체 리터럴 방식.
      • 객체를 변수로 선언해 사용.
    • 생성자 함수 방식.
      • 함수를 통해 객체를 생성하고 초기화.
    • Object.create() 방식.
      • 지정된 프로토타입 객체 및 속성(property)을 갖는 객체 생성.
        • 자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있음.
        • 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티(property) or 메소드(method)를 상속받아 사용할 수 있게 함.
        • 이러한 부모 객체를 Prototype(프로토타입) 객체 또는 줄여서 Prototype(프로토타입)이라 함.
  • 객체 리터럴 방식으로 처리.
    객체 리터럴(object literal) 방식

// 형식.
var object = {
  key1: value1,
  key2: value2,
  ...
}
<div class="card m-2" id="comments-new">
    <div class="card-body">
        	(생략)
                <input type="text" class="form-control" id="new-comment-nickname">
            (생략)
                <textarea type="text" class="form-control" rows="3" id="new-comment-body"></textarea>
			(생략)
                <input type="hidden" id="new-comment-article-id" value="{{id}}">
            (생략)
    </div>
</div>
<!--  댓글 작성하기  -->
<script>
    {
        // 댓글 생성 버튼 변수화.
        const commentCreateBtn = document.querySelector("#comment-create-btn");
        commentCreateBtn.addEventListener("click", function () {
            // 새 댓글 객체 생성.
            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);
        });
    }
</script>
  • 상수 타입의 comment 변수를 선언하고 nickname, body, articleId 키를 정의함.
    • 키 값은 querySelector()메서드로 가져옴.

  • 개발자 도구를 보면 콘솔에 객체생성된 것을 확인할 수 있음.

3-2. REST API 호출하고 응답처리.

  • fetch()함수는 웹 페이지에서 HTTP 통신을 하는 데 사용함.
    • GET, POST, PATCH, DELETE 같은 요청을 보내고 응답을 받을 수 있음.
// 형식. (Ex. POST일 경우)
fetch('API 주소', {
      method: "POST"	// 요청 메서드 (GET, POST, PATCH, DELETE)
    , headers: {    	// 헤더 정보.
        "Content-Type": "application/json"
    },
      body: JSON.stringify(객체)     // 전송 데이터.
}).then(response => {				// 응답을 받아 처리하는 구문.
    // 응답 처리문.
});
  • fetch()함수.
    • 첫 번째 전달값에는 API주소가 들어감.
    • 두 번째 전달값에는 요청 메서드(method), 헤더 정보(header), 전송 본문(body)이 들어감.
      • 전송 본문은 JSON형태로 보내야 하므로 JSON.stringify() 함수에 객체를 전달해서 JSON형태변환함.
  • 요청을 보내면 응답 객체response를 받음.
    • response 안에는 응답에 관한 정보가 들어있음.
const url = "/api/articles/" + comment.articleId + "/comments";
  • 상수(const) 타입의 url이라는 변수를 만들고 댓글 생성 API 주소를 저장.
    • API 주소에서 부모 게시글의 id는 매번 바뀌므로 comment.articleId로 작성하고 +연산자를 이용해서 앞뒤 주소와 연결.
// 비동기 통신을 위한 API -  fetch()
fetch(url, {
      method: "POST"
    , headers: {    // 전송 본문의 데이터 타입(JSON) 정보
        "Content-Type": "application/json"
    },
      body: JSON.stringify(comment)     // comment 객체를 JSON 문자열로 변환해서 전송.
});
  • 첫 번재 전달값으로 API 주소를 가지고 있는 url을 넘김.
  • 두 번째 전달값으로 요청 메서드, 헤더 정보, 전송 본문을 넘김.
    • 헤더 정보에는 전송 본문의 데이터 타입이 JSON임을 명시하는 내용이 들어감.


  • 콘솔에 객체가 만들어지고, DB에도 데이터가 삽입 됨.
      body: JSON.stringify(comment)
}).then(response => {
    // HTTP 응답 코드에 따른 메시지 출력.
    const msg = response.ok ? "댓글이 등록됐음." :"댓글 등록 실패!";
    alert(msg);
    // 페이지 새로 고침.
    window.location.reload();
});
  • response는 API 요청을 보내고 받은 응답 객체.
    • 응답 객체 상태가 ok면 전자, 아니면 후자를 msg변수에 저장한 후 alert()함수로 출력함.
  • 댓글 생성을 완료하고 메시지까지 잘 출력 됐다면 window.location.reload();으로 웹 페이지를 새로 고침.


  • 알림 메시지 확인 버튼을 누르면 자동으로 새로고침이 돼서 작성한 댓글이 보임.
profile
Every cloud has a silver lining.

0개의 댓글