카테고리 없음
과제 - 소통게시판 - 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