on
12) 게시판만들기 댓글처리
12) 게시판만들기 댓글처리
Reply댓글에 더미데이터 추가하기
mysql
랜덤한 5개번호에 댓글기능을 추가해둘것이다.
- 어떤 게시물은 댓글이 있고,
- 어떤 게시물을 댓글이 없고
board-mapper-ReplyMapper인터페이스
package org.zerock.jex01.board.mapper; import org.zerock.jex01.board.domain.Reply; import java.util.List; public interface ReplyMapper { int insert(Reply reply); //등록 }
resources-mapper-ReplyMapper.xml
insert into tbl_reply(bno, replyer, reply) values (#{bno},#{replyer},#{reply})
test -ReplyMapperTests
package org.zerock.jex01.board.mapper; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.zerock.jex01.board.config.BoardRootConfig; import org.zerock.jex01.board.domain.Reply; import org.zerock.jex01.common.config.RootConfig; import java.util.stream.IntStream; @Log4j2 @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {BoardRootConfig.class, RootConfig.class}) public class ReplyMapperTests { @Autowired(required = false) //스프링이로딩될때 Autowired가능한지 체크하지 않는다. ReplyMapper replyMapper; @Test public void insertDommies() { long[] arr = {124L,128L,100L,110L,99L}; //5개 랜덤 번호 정함(게시물번호) IntStream.rangeClosed(1,100).forEach(num -> { // long bno = arr[(int)(Math.random())*arr.length]; //0,1,2,3,4 long bno = arr[(int)(Math.random()*1000) % 5]; //0,1,2,3,4 Reply reply = Reply.builder() .bno(bno) .reply("댓글....." + num) .replyer("user" + (num % 10)) //0~9까지 .build(); replyMapper.insert(reply); }); }
db결과 확인
100개데이터 들어갔다.
특정한 게시물번호를가지고 댓글목록조회
예)
select * from tbl_reply where bno = 100 order by rno asc ;
board-mapper-ReplyMapper인터페이스
package org.zerock.jex01.board.mapper; import org.zerock.jex01.board.domain.Reply; import java.util.List; public interface ReplyMapper { int insert(Reply reply); //등록 List getListWithBoard(Long bno); //게시물번호에 해당하는 댓글목록 }
resources-mapper-ReplyMapper.xml
select * from tbl_reply where bno = #{bno} order by rno asc
->resultType은 vo객체인 db와 직접적인관계있는것을 type으로 준다!
test -ReplyMapperTests
@Test public void testList() { Long bno = 128L; replyMapper.getListWithBoard(bno).forEach(reply -> log.info(reply)); }
log4jdbc덕분에 결과잘 나옴!! (128번 게시물에해당하는댓글목록) 128번에 해당하는 댓글목록
게시판안에 댓글목록나오는것 처리하는것을
조인,서브쿼리(쿼리안에 쿼리)
으로 처리한다.
-> 정규화(데이터베이스에 정말 필요한 데이터를 남겨두자라는 의미였는데)
이거와 반대되는 "반정규화"하다!
반정규화됐다는것은 (데이터가 중복된데이터가 있고, 계산되는 값을 컬럼으로 잡지 않는다.)
ex) 생년월일, 나이
아예 나이같은것처럼 계산되는 값을 컬럼을 빼두자.
지금 보면 댓글수같은경우는계산되서 증가되어야하기때문에 -> db에 컬럼저장이적합하지 않다.
이런것을 반정규화라한다.
하지만,
이거때문에 이거때문에 조인을 한다면(댓글수때문에..) 성능 저하가 되기 때문에
어쩔 수 없이 반정규화를 하도록한다.
mysql tbl_board테이블의 댓글 수 컬럼명 추가
default 0으로(처음에는댓글이없으니까)
update tbl_board set replyCnt = (select count(bno) from tbl_reply where tbl_reply.bno = tbl_board.bno) where bno > 100 ;
댓글수는 = 쿼리의 실행결과(댓글번호와 게시판번호가 같은것 번호의 수)로 업데이트 할것이다.
조건을 잠깐준다. bno가 100인..
목록(특정게시물에해당하는 댓글목록)
board-service-ReplyService인터페이스
인터페이스는 원래 추상메소드나 상수밖에 안됐는데, default를 붙임으로써 몸체를 가질 수 있다.
vo(Reply) -> dto(ReplyDTO)
package org.zerock.jex01.board.service; import org.zerock.jex01.board.domain.Reply; import org.zerock.jex01.board.dto.ReplyDTO; import java.util.List; public interface ReplyService { List getRelipesWithBno(Long bno); //게시물에 해당하는 댓글목록 //인터페이스는 원래 메소드를 가질 수 없지만 default를 쓰면 실제로 몸체를 가지는 메서드를 가질 수 있다. default ReplyDTO entityToDTO(Reply reply) { ReplyDTO replyDTO = ReplyDTO.builder() .rno(reply.getRno()) .bno(reply.getBno()) .reply(reply.getReply()) .replyer(reply.getReplyer()) .replyDate(reply.getReplyDate()) .modDate(reply.getModDate()) .build(); return replyDTO; }
board-service-ReplyServiceImpl구현받는 클래스
package org.zerock.jex01.board.service; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; import org.zerock.jex01.board.dto.ReplyDTO; import org.zerock.jex01.board.mapper.ReplyMapper; import java.util.List; import java.util.stream.Collectors; @Service @Log4j2 @RequiredArgsConstructor public class ReplyServiceImpl implements ReplyService{ private final ReplyMapper replyMapper; @Override public List getRelipesWithBno(Long bno) { //Reply -> ReplyDTO 변환해서(map) list로 반환 //댓글(db와연결된 vo entity) -> 댓글dto(객체타입) return replyMapper.getListWithBoard(bno).stream().map(reply -> entityToDTO(reply)).collect(Collectors.toList()); }
board-controller-ReplyController
package org.zerock.jex01.board.controller; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.web.bind.annotation.*; import org.zerock.jex01.board.dto.ReplyDTO; import org.zerock.jex01.board.service.ReplyService; import java.util.List; @Log4j2 @RestController //@ResponseBody걸린다. @RequestMapping("/replies") @RequiredArgsConstructor public class ReplyController { private final ReplyService replyService; @GetMapping("/list/{bno}") //replies/list/128 (REST방식) public List getBoardReplies(@PathVariable(name="bno") Long bno) { //서비스 계층 호출 return replyService.getRelipesWithBno(bno); } }
특정 게시물(bno=128)의 댓글 목록
package org.zerock.jex01.board.dto; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.time.LocalDateTime; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class ReplyDTO { private Long rno; private Long bno; private String replyer; private String reply; @JsonFormat(shape=JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime replyDate; @JsonFormat(shape=JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime modDate; } ReplyDTO의 JsonFormat으로 pattern을 지정해준다.
등록(댓글등록)
service - ReplyService인터페이스
나중 수정이나 삭제를 대비해서 dto -> vo로 바꾸는 코드 (객체 -> db)
//dto -> entity로바꿔줌 default Reply dtoToEntity(ReplyDTO replyDTO) { Reply reply = Reply.builder() .rno(replyDTO.getRno()) .bno(replyDTO.getBno()) .reply(replyDTO.getReply()) .replyer(replyDTO.getReplyer()) .replyDate(replyDTO.getReplyDate()) .modDate(replyDTO.getModDate()) .build(); return reply; }
//add추가!
int add(ReplyDTO replyDTO); //등록
//전체코드
package org.zerock.jex01.board.service; import org.zerock.jex01.board.domain.Reply; import org.zerock.jex01.board.dto.ReplyDTO; import java.util.List; public interface ReplyService { List getRelipesWithBno(Long bno); //게시물에 해당하는 댓글목록 int add(ReplyDTO replyDTO); //등록 //인터페이스는 원래 메소드를 가질 수 없지만 default를 쓰면 실제로 몸체를 가지는 메서드를 가질 수 있다. default ReplyDTO entityToDTO(Reply reply) { ReplyDTO replyDTO = ReplyDTO.builder() .rno(reply.getRno()) .bno(reply.getBno()) .reply(reply.getReply()) .replyer(reply.getReplyer()) .replyDate(reply.getReplyDate()) .modDate(reply.getModDate()) .build(); return replyDTO; } //dto -> entity로바꿔줌 default Reply dtoToEntity(ReplyDTO replyDTO) { Reply reply = Reply.builder() .rno(replyDTO.getRno()) .bno(replyDTO.getBno()) .reply(replyDTO.getReply()) .replyer(replyDTO.getReplyer()) .replyDate(replyDTO.getReplyDate()) .modDate(replyDTO.getModDate()) .build(); return reply; }
servie-ReplyServiceImpl 구현하는 클래스
package org.zerock.jex01.board.service; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; import org.zerock.jex01.board.dto.ReplyDTO; import org.zerock.jex01.board.mapper.ReplyMapper; import java.util.List; import java.util.stream.Collectors; @Service @Log4j2 @RequiredArgsConstructor public class ReplyServiceImpl implements ReplyService{ private final ReplyMapper replyMapper; @Override public List getRelipesWithBno(Long bno) { //Reply -> ReplyDTO 변환해서(map) list로 반환 //댓글(db와연결된 vo entity) -> 댓글dto(객체타입) return replyMapper.getListWithBoard(bno).stream().map(reply -> entityToDTO(reply)).collect(Collectors.toList()); } @Override public int add(ReplyDTO replyDTO) { return replyMapper.insert(dtoToEntity(replyDTO)); //dto -> entity로바꿔줌 }
-> dto객체를 entity db에서 mapper.xml할 수 있도록 추가해준다.
controller - ReplyController
@PostMapping("") public int add(@RequestBody ReplyDTO replyDTO){ //댓글 등록 log.info("=========================="); log.info(replyDTO); return replyService.add(replyDTO); }
//전체코드
package org.zerock.jex01.board.controller; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.web.bind.annotation.*; import org.zerock.jex01.board.dto.ReplyDTO; import org.zerock.jex01.board.service.ReplyService; import java.util.List; @Log4j2 @RestController //@ResponseBody걸린다. @RequestMapping("/replies") @RequiredArgsConstructor public class ReplyController { private final ReplyService replyService; @GetMapping("") public String[] doA(){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return new String[]{"AAA","BBB","CCCC"}; } @GetMapping("/list/{bno}") //replies/list/128 (REST방식) public List getBoardReplies(@PathVariable(name="bno") Long bno) { //특정게시물에대한 댓글목록 //서비스 계층 호출 return replyService.getRelipesWithBno(bno); } @PostMapping("") public int add(@RequestBody ReplyDTO replyDTO){ //댓글 등록 log.info("=========================="); log.info(replyDTO); return replyService.add(replyDTO); }
수정
board-mapper-ReplyMapper인터페이스
int update(Reply reply); //수정
resourecs-mapper-ReplyMapper.xml
update tbl_reply set reply = #{reply}, modDate = now() where rno = #{rno}
-> 수정할 때 필요한것은 rno
-> 바꿀 수 있는 것은 내용!만 가능
-> 시간은 현재시간으로 바꿔주기(최종적으로 바뀐시간)
board-service-ReplyService인터페이스
int modify(ReplyDTO replyDTO);
board-service-ReplyServiceImpl 구현받는 클래스
@Override public int modify(ReplyDTO replyDTO) { return replyMapper.update(dtoToEntity(replyDTO)); } //dto->entity로바꿔줌
board-controller-ReplyController
@PutMapping("/{rno}") public String modify( @PathVariable(name="rno") Long rno, @RequestBody ReplyDTO replyDTO){ log.info("-------------reply modify-------------" + rno); log.info(replyDTO); replyService.modify(replyDTO); return "success"; }
삭제
board-mapper-ReplyMapper인터페이스
int delete(Long rno); //삭제
resourecs-mapper-ReplyMapper.xml
delete from tbl_reply where rno = #{rno}
board-service-ReplyService인터페이스
int remove(Long rno);
board-service-ReplyServiceImpl 구현받는 클래스
@Override public int remove(Long rno) { return replyMapper.delete(rno); }
board-controller-ReplyController
@DeleteMapping("/{rno}") public String remove( @PathVariable(name="rno") Long rno ){ log.info("----------------reply remove------------"); log.info("rno: " + rno); replyService.remove(rno); return "success"; }
댓글등록, 모달띄우기, 목록출력
자바스크립트로 처리하기
흐름도
더보기 자바스크립트가 dom처리, 이벤트처리,axios(ajax처리) 등등 혼자서 하는 게 많아서 더 좋은 라이브러리가 생긴게 '리엑트'나 '뷰' '앵귤러' 등등이 있는 것이다.. 그래서 우리는 지금 기본적인 js 이벤트 처리, dom처리(html/css/js script부분) axios처리하기위한 script추가 해놓고 - read.jsp에서 (조회페이지에서) 따로 axios부분 즉 비동기처리하는 ajax처리하는 부분만 따로 빼둔것이 reply.js에서 한다!
비동기처리란?
비동기처리에는 콜백함수와 return으로 asyns, await처리하는 방식이 있었는데,
콜백함수는 이제 안쓰는 추세이고 asyns, await로 비동기 처리한다!!!
비동기처리 중 asyns, await는 promise약속어음을 주는 데, 그 주는 동안 then을 사용해서 데이터 가져와서 출력
axios와 리엑트와는 같은 의미이다.
axios는 객체를 문자열로 반환해주는 json을 자동으로 포함하고 있다! (내가 따로 선언하지 않아도 자동으로나옴)
* 참고로 ajax로 데이터 주고받을 때 보안문제로 CORS가 있었는데. 동일한 도메인 즉 사이트에서만가능했다.
(웹스톤, 인텔리제이 중복해서 접근 x) 이러한 보안문제로 Filter를 사용해서 ajax할때 통용되도록 수정하기도 한다.
2021.08.28 - [학원용] - CORS
즉, ajax로 서버를 통신할때는 무조건 "비동기처리"이다!!!!
하나의 서버에서 통신하는 것이 아닌
한개의 페이지에서 여러 개의 서버를 통신할 수 있는
예로 키오스트가 있었다.
* -> 서버
-> 서버
-> 서버
2021.08.27 - [학원용] - AJax
댓글 목록 (특정게시물에 해당하는 댓글목록리스트)
webapp-js-reply.js
const getReplyList = async (bno) => { const response = await axios.get(`/replies/list/${bno}`) return response.data }
-> 응답한 데이터 보내줌! (비동기처리로 ajax로 데이터 가져와서 뿌려줌-응답)
WEB-INF-views-read.jsp
댓글을 언제 가져올것인가?
1. jsp가 열리자마자 댓글을 가져온다. read.jsp 조회페이지 갔을 때
2. 댓글보기라는 버튼을 눌렀을 때 댓글을 가져온다.
- 서버의 부하를 줄이기 위해서 댓글갯수 몇개있음 나오고 댓글보기 버튼누르면 ajax로 데이터 가져와서 뿌려주죠.
-> 일단 우리는 간단하게 하기위해서 열리자마자 함수 실행하도록 할 것이다.
■ js 즉시실행함수란?
- 함수를 만들자마자 () 묶어서 선언하면 딱 한번만 호출된다.
(function() {
})()
() 괄호의 의미가 실행한다는 의미였다.
-> 즉 이렇게 열리자마자 함수가 단 한번만 호출
이 부분은 그냥 목록과 수정버튼의 이벤트 처리
내가 작성한 댓글을 삭제합니다. 그 사이에 또 다른 댓글이 추가되거나,수정,삭제되는 가능성이 있기 때문에 또 다시 가져와야 해서, 결과적으로 댓글을 또 가져와야하기때문에
아예 댓글을 목록을 매번 작업이 끝난 후 호출을 하도록 한다.
↓
별도의 함수로 빼주는 것이다.
function getList() { const target = document.querySelector(".direct-chat-messages") const bno = '${boardDTO.bno}' // 게시글의 번호 //즉시실행 안하고 왜 바로 함수로 뺐을 까? 매번 작업이 끝난 후 호출을 하도록 해야하기때문에 별도의 함수로 빼준다. getReplyList(bno).then(data => { console.log(data) //array 배열의 갯수만큼 위의 temp가 반복되어서 추가되어야한다. }) } //최초실행 (function () { getList() })()
댓글을 가져온다.
밑에 댓글 부분을 만들어 준다. vs코드로 열기
밑에 댓글목록 만들기 위한
복사
WEB-INF-views-read.jsp
- 밑에 붙여넣기
- 필요없는 부분은 삭제
- 댓글등록버튼 Add Reply
class 값으로 addReplyBtn
이부분은 댓글내용이라서 계속 반복해서 댓글내용을 보여줄 것이기 때문에 복사 후 함수로 빼준다!!
더보기 * 한글 깨졌다면 추가
function getList() { const target = document.querySelector(".direct-chat-messages") //게시물 내용 const bno = '${boardDTO.bno}' // 게시글의 번호 //함수 하나 만들기 function convertTemp(replyObj) { console.log(replyObj) const {rno,bno,reply,replyer,replyDate,modDate} = {...replyObj} //펼쳐서 보여준다. (빵바른다,빵칼) //벡틱을써서 반복되는 부분을 따로 뺌 const temp =` \${rno} -- \${replyer} \${replyDate} \${reply} ` return temp } //array 배열의 갯수만큼 위의 temp가 반복되어서 추가되어야한다. getReplyList(bno).then(data => { //번호에해당하는 댓글 가져와서 그데이터를 출력 console.log(data) let str = ""; //변수 하나 잡아주기 data.forEach(reply => { str += convertTemp(reply) //댓글들을 담아서 저장 }) target.innerHTML = str //게시물내용에다가 댓글들을 저장 }) } //최초실행 (function () { getList() })()
더보기 const {rno,bno,reply,replyer,replyDate,modDate} = {...replyObj} //펼쳐서 보여준다. (빵바른다,빵칼) "전개연산자"라고한다. 쫙 펴주는 (리엑트에서 나오니까 알아두자) 변수를 여러 개 잡고 그것을 쫙 펴서 보여준다. replyObj에 있던 내용이 쫙 펴서 보여준다. 이렇게 쫙 펴서 보여준다.
console.log에도 잘찍힌다.
- 댓글에 해당하는 것들 반복해서 잘 나온다!
서버 로그도 잘 찍힘
-128번 게시물에 대한 댓글 목록
모달창 추가
버튼이벤트 (모달처리위함) vs코드로 열기
모달처리하기위한
WEB-INF-views-read.jsp
-list.jsp에 있는 model부분 복사
-read.jsp에 붙여넣기
모달버튼을 위한 addReplyBtn이라는 class이름
operBtn을 클릭했을 시 이벤트준다.
form태그를 쓰지 않기 때문에 name은 우리가 맘대로 지정해준다.
버튼을 여러용도로 사용할 건데
삭제를 클릭했을때 버튼의 operBtn의 값이 바뀔것이다.
//모달창 const modalDiv = $("#modal-sm") //제이쿼리로 표현 let oper = null document.querySelector(".addReplyBtn").addEventListener("click", function(){ //AddReply버튼 클릭시(댓글등록) oper = 'add' modalDiv.modal('show')//모달보여준다. },false)
document.querySelector(".operBtn").addEventListener("click", function (){ //Save Change버튼 클릭시(저장) const bno = '${boardDTO.bno}' const replyer = document.querySelector("input[name='replyer']").value const reply = document.querySelector("input[name='reply']").value //add 버튼을 클릭하면 윗 3개 변수가 다 필요하다. if(oper === 'add') { // console.log(bno,replyer,reply) //위에서 제대로 받아왔는지 확인 - 화면 쪽 처리 const replyObj = {bno, replyer, reply} // {bno:bno, replyer:replyer, reply:reply} 와 같은 코드이고 동일한의미 리엑트,뷰 등 이렇게 쓰기때문에 봐둬야한다. {bno,repyer}이런식으로 쓰기때문에 console.log(replyObj) //버튼클릭후 addReply로 객체던저셔 보내주고 데이터 뿌려주고 (js에서 axios에서) addReply(replyObj).then(result => { getList() //다시 목록데이터 보여줘야한다. (ajax비동기 호출이 2번 일어나는 것이다. addReply(등록)와 getList에서의 getReplyList(목록데이터출력) modalDiv.modal('hide')//모달숨김 document.querySelector("input[name='replyer']").value ="" document.querySelector("input[name='reply']").value ="" }) } },false)
- 버튼을 클릭하면 입력했던 내용을 알아와서 axios로 데이터 보내려고하는거임
버튼을 클릭했을 때 'add'라면
잘 가져왔는지 찍어줌
- ajax호출이 2번일어나는것이다.
add로 등록일때 그 객체를 가지고 addReply가 있는 -> reply.js에서 비동기처리로 등록 후 데이터 처리해주고
getList()로 (위에 함수로 빼둠)
function getList() { const target = document.querySelector(".direct-chat-messages") //게시물 내용 const bno = '${boardDTO.bno}' // 게시글의 번호 //함수 하나 만들기 function convertTemp(replyObj) { console.log(replyObj) const {rno,bno,reply,replyer,replyDate,modDate} = {...replyObj} //펼쳐서 보여준다. (빵바른다,빵칼) //벡틱을써서 반복되는 부분을 따로 뺌 const temp =` \${rno} -- \${replyer} \${replyDate} \${reply} ` return temp } //array 배열의 갯수만큼 위의 temp가 반복되어서 추가되어야한다. getReplyList(bno).then(data => { //번호에해당하는 댓글 가져와서 그데이터(목록)를 출력 console.log(data) let str = ""; //변수 하나 잡아주기 data.forEach(reply => { str += convertTemp(reply) //댓글들을 담아서 저장 }) target.innerHTML = str //게시물내용에다가 댓글들을 저장 }) } //최초실행 (function () { getList() })()
즉 getList일때도 getReplyList -> reply.js에서 비동기처리로 목록데이터 처리후 뿌려준다. (ajax통신 - axios)
결국 등록 후 데이터 목록 뿌려주고 모달 숨김 'hide'
getAttribute("value")와 .value의 차이?
const replyer = document.querySelector("input[name='replyer']").value const reply = document.querySelector("input[name='reply']").value
getAttribute로 하면 값을 잘 읽어올 수 가없어서.. null로 뜸
그래서 value로 해야 제대로 나온다.
(자바스크립트는 언제는되고, 언제는 안되고,,,,,,)
webapp-js-reply.js
const getReplyList = async (bno) => { //목록데이터 보내줌 const response = await axios.get(`/replies/list/${bno}`) return response.data } async function addReply(obj){ //모달등록 시 데이터 보내줌 const response = await axios.post("/replies", obj) return response.data }
댓글등록
새로고침후 등록완료 후 데이터 뿌려줌 -> 모달 숨김!
modalDiv.modal('hide')//모달숨김 document.querySelector("input[name='replyer']").value ="" document.querySelector("input[name='reply']").value =""
-> 모달 숨기면서 value를 "" 비워두니까 새로운 댓글 추가할 시 모달창의 내용을 사라진 것을 확인할 수 있다!
수정/삭제
댓글 내용을 클릭했을 때
모달창을 띄어야하는데,,
댓글번호, replyer,reply등등 다 필요하다
즉 댓글 전체가 다 필요하다.
한 페이지 내에서 등록, 수정, 삭제 자바스크립트로 다 처리하기 때문에 좀 좋진않다.
WEB-INF-board-read.jsp
- 모달 수정,삭제 부분 추가
(ul - model.html태그 부분 수정,삭제에서 사용할 모달 부분 태그 복사 후 붙여넣기)
- 모달 수정,삭제 div 모달태그에서
- 수정,삭제버튼 생성
태그부분
//수정,삭제 dom 관련 const modModal = $("#modal-lg") //jquery로 바꿔줘야 한다 modal이라는 함수가 없기 때문 const modReplyer = document.querySelector("input[name='replyerMod']") const modReply = document.querySelector("input[name='replyMod']") const modRno = document.querySelector("input[name='rno']") document.querySelector(".direct-chat-messages").addEventListener("click", (e)=> { const target = e.target const bno = '${boardDTO.bno}' if(target.matches(".direct-chat-text")){ //custom data 속성 const rno = target.getAttribute("data-rno") const replyer = target.getAttribute("data-replyer") const reply = target.innerHTML console.log(rno, replyer, reply, bno) //dom 부분에 대입 modRno.value = rno modReply.value = reply modReplyer.value = replyer document.querySelector(".btnRem").setAttribute("data-rno",rno) modModal.modal('show') //모달창 보여줌 } },false)
-> matches로 확인 그 이벤트 클릭한거와 입력된데이터와 같다면
댓글번호, 댓글작성자 가져오고
이벤트에 innerHTML로 추가 해준다 내용에!
그 input부분에 (dom부분이죠?) 그 번호와,내용,작성자를 넣어준다.
(그럼 모달창 떴을 때 값이 보여진다)
삭제버튼 클릭 시 댓글번호를 가져온 뒤 모달창 띄어준다!
//delete document.querySelector(".btnRem").addEventListener("click", (e)=> { //삭제버튼을 클릭 시 const rno = e.target.getAttribute("data-rno") //이벤트(e)에해당하는 rno값을 가져와서 //alert(rno) removeReply(rno).then(result => { //axios 데이터 삭제 처리후 뿌려줌 getList() //삭제 완료 후 list getReplyList axios처리후 목록 데이터 뿌려줌 modModal.modal("hide") //모달 감춤 }) },false) //modify document.querySelector(".btnModReply").addEventListener("click", (e) => { //수정 버튼 클릭 시 const replyObj = {rno: modRno.value , reply: modReply.value } console.log(replyObj) modifyReply(replyObj).then(result => { //수정 modifyReply axios데이터 처리 후 데이터 뿌려줌 getList() //수정 처리 후 list getReplyList axios처리후 목록 데이터 뿌려줌 modModal.modal("hide") //모달 감춤 }) },false);
-> 수정버튼 클릭시 dom의 값을 그 현재 번호와 현재 작성자의 값으로 넣어서 replyObj 변수에 대입
그 변수에 넣어진 값을 가지고 axios 데이터 처리하러 간다. reply.js
수정 후 list 뿌려줌
모달 감춤
webapp-js-reply.js
const removeReply = async (rno) => { const response = await axios.delete(`/replies/${rno}`) return response.data } const modifyReply = async (reply) => { // async - await const response = await axios.put(`/replies/${reply.rno}`,reply) return response.data }
수정
삭제
-> 삭제되서 목록에서도 사라지고 모달창도 사라짐
즉 삭제 처리 후 목록데이터 보여주고 모달창 가림!
from http://hanna97.tistory.com/390 by ccl(A) rewrite - 2021-09-15 23:27:17