카테고리 없음

과제 - 소통게시판 - 5 --- 댓글 뷰 설계

parkrams 2023. 7. 1. 19:29
728x90

댓글 처리와 자바스크립트

댓글 목록 처리

  • 필요한 기능 설계
    • bno : 현재 게시물 번호
    • page : 페이지 번호
    • size : 페이지당 사이즈
    • goLast : 마지막 페이지 호출 여부
      • goLast를 이용해 강제적으로 마지막 댓글 페이지 호출 하도록 설정
  • reply.js 에 getList 함수 작성
async function getList({bno, page, size, goLast}){
    const result = await axios.get(`/replies/list/${bno}`, {params: {page, size}})
    return result.data
}
  • read.html 에는 getList()를 호출하는 함수와 현재 페이지가 로딩되면 해당 함수를 호출하도록 작성
    function printReplies(page, size, goLast){

        getList({bno, page, size, goLast}).then(
            data => {console.log(data)}
        ).catch( e =>
            console.error(e))
    }

    printReplies(1,10) // 무조건 호출
  • dtoList로 화면에 목록 replyList 를 처리하고, 나머지 정보들로 페이지 번호들을 출력
  • read.html 에 댓글목록을 출력하는 printList() 와 페이지 번호를 출력하는 printPages() 함수를 작성
 const replyList = document.querySelector('.replyList') // 댓글 목록 DOM
    const replyPaging = document.querySelector('.replyPaging') // 페이지 목록 DOM

    function printList(dtoList){   // 댓글 목록 출력
        let str = '';
        if(dtoList && dtoList.length > 0 ){
            for(const dto of dtoList){

                str += `<li class="list-group-item d-flex replyItem">
                      <span class="col-2">${dto.rno}</span>
<!--                      댓글 번호 -->
                      <span class="col-6" data-rno="${dto.rno}">${dto.replyText}</span>
<!--                      댓글 작성자 -->
                      <span class="col-2">${dto.replier}</span>
                      <span class="col-2">${dto.regDate} </span>
                    </li>`
            }
        }
        replyList.innerHTML = str
    }

    function printPages(data){ //페이지 목록 출력

        //pagination
        let pageStr = '';

        if(data.prev) {
            pageStr +=`<li class="page-item"><a class="page-link" data-page="${data.start-1}">PREV</a></li>`
        }

        for(let i = data.start; i <= data.end; i++){
            pageStr +=`<li class="page-item ${i == data.page?"active":""} "><a class="page-link" data-page="${i}">${i}</a></li>`
        }

        if(data.next) {
            pageStr +=`<li class="page-item"><a class="page-link" data-page="${data.end +1}">NEXT</a></li>`
        }
        replyPaging.innerHTML = pageStr
    }

    // Axios  결과를 가져 오면 앞으 함수들에게 전달
    function printReplies(page,size,goLast) {

        getList({bno, page, size, goLast}).then(
            data => {
                printList(data.dtoList) //목록 처리
                printPages(data) //페이지 처리
            }
        ).catch(e => {
            console.error(e)
        })
    }

    printReplies(1,10) // 무조건 호출
@JsonFormat, @JsonIgnore
  • 출력 부분이 배열로 처리되어 조금 지저분 해 보인다.
  • ReplyDTto 에 @JsonFormat 을 이용해 Json 처리시 포맷팅 지정
  • 댓글 수정시간은 출력할 일이 없으므로 @JsonIgnore을 적용
  • ReplyDto
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private LocalDateTime regDate;

    @JsonIgnore
    private LocalDateTime modDate;

댓글 등록

---------- 23-7-2 ----------------

모달로 처리 할 건데 모달이 자꾸 안된다 --...--...

  • reply.js에 새로운 댓글을 등록하는 기능 추가
  • 파라미터를 JS의 객체로 받아서 axios.post()를 이용해 전달
async function addReply(replyObj){
    const response = await axios.post(`/replies/`, replyObj)
    return response.data
}
  • addReply()가 정상적으로 처리되면 서버에는 JSON 데이터를 전송하게 되는데 이를 이용해서 댓글이 추가되면 경고창을 보여주고 마지막 페이지로 이동해서 등록된 댓글을 볼 수 있게 구성
  • read.html 에 댓글 등록을 위한 모달창 추가

모달 창 드디어 뜬다!

  • 안됐던 이유를 찾고 싶다...
  • 예상 안 됐던 이유... -> div 문제...?
  • reply.js
async function addReply(replyObj){
    const response = await axios.post(`/replies/`, replyObj)
    return response.data
}
  • read.html
<div class="modal registerModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Register Reply</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>

            </div>
            <div class="modal-body">
                <div class="input-group mb-3">
                    <span class="input-group-text">Reply Text</span>
                    <input type="text" class="form-control replyText">
                </div>
                <div class="input-group mb-3">
                    <span class="input-group-text">Replier</span>
                    <input type="text" class="form-control replier" >
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary registerBtn">Register</button>
                    <button type="button" class="btn btn-outline-dark closeRegisterBtn" >Close</button>
                </div>
            </div>
        </div>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="/js/reply.js"></script>
</div>
</div>


<script layout:fragment="script" th:inline="javascript">

    //댓글 등록 모달
    const registerModal = new bootstrap.Modal(document.querySelector(".registerModal"))

    //  registerModal
    const registerBtn = document.querySelector(".registerBtn")
    const replyText = document.querySelector(".replyText")
    const replier = document.querySelector(".replier")
    const closeRegisterBtn = document.querySelector(".closeRegisterBtn")
  • close 버튼 동작 까지
  • add 버튼 동작 추가
 // add  누를 때 동작
    registerBtn.addEventListener("click", function (e){
        const replyObj = {
            bno:bno,
            replyText:replyText.value,
            replier:replier.value}

        addReply(replyObj).then(result => {
            alert(result.rno)
            registerModal.hide()
            replyText.value = ''
            replier.value = ''
            printReplies(1, 10, true) // 댓글 목록 갱싱
        }).catch(e => {
            alert("예외...")
        })
    }, false)
  • 애드 동작 확인 !! 경고창 뜨고 댓글 등록 되는 부분 까지

댓글 페이지 번호 클릭으로 이동

  • 새로운 댓글이 추가되면 자동으로 마지막 페이지로 이동하기는 하지만, 댓글의 페이지 번호를 누를 때도 이동할 수 있으므로 수정/삭제 전에 페이지 이동 처리를 먼저 진행
  • 화면에서 페이지 번호를 구성하는 부분인 <li> 태그 내에 존재하는 <a> 태그이고 페이지 번호가 'data-page'속성 값으로 지정됨
  • 페이지 번호는 매번 새로이 번호를 구성 하므로 이벤트 처리는 항상 고정 되어 있는 <ul>을 대상으로 이벤트 리스너 등록 방식 이용
  • read.html 에 코드 추가
// 댓글 페이지 번호 눌러도 이동
    let page = 1
    let size = 10

    replyPaging.addEventListener("click", function (e){
        e.preventDefault()
        e.stopPropagation()

        const target = e.target

        if(!target || target.tagName != 'A'){
            return 
        }
        const pageNum = target.getAttribute("data-page")
        page = pageNum
        printReplies(page, size)
    }, false)

스크립트 제일 밑 부분에 작성할 것

  • page 와 size를 별도의 변수로 처리한 것은 나중에 댓글 수정과 같은 작업에서 현재 페이지 번호를 유지해야 할 가능성이 있음
  • 이벤트 처리가 완료 되면 댓글 페이지 이동 가능

댓글 조회와 수정

  • 조회는 수정이나 삭제를 위해 작성
  • 조회는 등록과 유사하게 모달창을 이용해서 수정이나 삭제가 가능한 버튼을 보여주는 형태로 구성
axios 통신 부분
  • reply.js에는 특정한 번호의 댓글을 조회 하고 수정할 수 있는 기능을 다음과 같이 구성
  • 댓글 조회는 GET방식으로 처리되고, 수정은 PUT 방식을 호출
read.html의 모달창 처리 댓글 수정 모달창 뜬다 !!!!
  • 어.. 눌렀을 때 댓글 수정 할 수 있도록 특정 댓글의 모달창이 뜬다..
  • 댓글 등록 과 댓글 수정 모달창 - read.html 에 추가
 <div class="modal registerModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Register Reply</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>

                </div>
                <div class="modal-body">
                    <div class="input-group mb-3">
                        <span class="input-group-text">Reply Text</span>
                        <input type="text" class="form-control replyText">
                    </div>
                    <div class="input-group mb-3">
                        <span class="input-group-text">Replier</span>
                        <input type="text" class="form-control replier">
                    </div>
                </div>   <------------------------- 이부분에 하나 빠트렸었음... 
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary registerBtn">Register</button>
                    <button type="button" class="btn btn-outline-dark closeRegisterBtn">Close</button>
                </div>
            </div>
        </div>
    </div> <!------ end register modal ----->

        <div class="modal modifyModal" tabindex="-1">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title replyHeader"></h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <div class="input-group mb-3">
                            <span class="input-group-text">Reply Text</span>
                            <input type="text" class="form-control modifyText">
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-info modifyBtn">Modify</button>
                        <button type="button" class="btn btn-danger removeBtn">Remove</button>
                        <button type="button" class="btn btn-outline-dark closeModifyBtn">Close</button>
                    </div>
                </div>
            </div>
        </div> <!----------modifyModal------>
  • div 닫는 부분 잘 확인 . modal-body 잘 안 닫으니까 오류 생겼었음.
  • 수정 모달
//수정 모달  - script 부분 
    const modifyModal = new bootstrap.Modal(document.querySelector(".modifyModal"))

    const replyHeader = document.querySelector(".replyHeader")
    const modifyText = document.querySelector(".modifyText")
    const modifyBtn = document.querySelector(".modifyBtn")
    const removeBtn = document.querySelector(".removeBtn")
    const closeModifyBtn = document.querySelector(".closeModifyBtn")

    // 특정한 댓글을 눌렀을 때 모달창이 보이도록
    replyList.addEventListener("click", function (e) {

        e.preventDefault()
        e.stopPropagation()

        const target = e.target

        if (!target || target.tagName != 'SPAN') {
            return
        }

        const rno = target.getAttribute("data-rno")

        if (!rno) {
            return
        }
        getReply(rno).then(reply => { // 댓글의 내용을 모달창에 채워서 보여주는
            console.log(reply)
            replyHeader.innerHTML = reply.rno
            modifyText.value = reply.replyText
            modifyModal.show()
        }).catch(e => alert('error'))
    }, false)
댓글 수정과 화면 갱신
  • modify 버튼에 대한 이벤트 처리와 모달창 close 버튼의 이벤트 처리를 작성
  • 댓글 수정 --- reply.js
// 댓글 수정
async  function modifyReply(replyObj){
    const response = await axios.put(`/replies/${replyObj.rno}`, replyObj)
    return response.data
  • read.html
    // modify 버튼에 대한 이벤트 처리와 모달창의 close 버튼의 이벤트 처리
    modifyBtn.addEventListener("click", function (e){

        const replyObj = {
            bno: bno,
            rno: replyHeader.innerHTML,
            replyText: modifyText.value}
        modifyReply(replyObj).then(result =>{
            alert (result.rno + ' 댓글 수정 됐어요')
            replyText.value = ''
            modifyModal.hide()
            printReplies(page, size)
        }).catch(e => {
            console.log(e)
        })

    }, false)

  • 댓글 삭제 - reply.js
// 댓글 삭제
async function removeReply(rno){
    const response = await axios.delete(`replies/${rno}`)
    return response.data
}
  • read.html - script 부분

 

 

-------------- 7월 8일 부터 다시 시작 

728x90