Team Project 2일차
어제의 TIL에도 적어놨듯이 이번 프로젝트에서 내가 맡은 역할은 댓글 기능을 만드는 것이다.
어제까지 firebase와 local stroge에 넣고 데이터를 가져온 뒤 웹에 구현하는 것까지 성공했는데(두 방식 모두 해봄), 오늘 할일은 기본적으로 구현한 기능에 부가적으로 몇 가지 추가하고 변경하는 작업을 했다.
오늘 project에서 내가 할 일은 크게 7가지 정도 있었다. (혼자 구상해본 할 일)
① 작성자, 댓글, 날짜 댓글 창에 동시에 띄우기
② 댓글 최신순서로 띄우기, 댓글 작성시 맨 위에 뜨게 하기(시간순 정렬)
③ 수정, 삭제 버튼 추가하기
④ 영화별로 기능 구현하기
⑤ click버튼 submit으로 바꾸기
⑥ 페이지가 로드되면 firebase의 내용을 전부 꺼내고 시작하게 만들기
⑦ 댓글에 스크롤 기능 넣기
이 중에서 ④번을 제외한 모든 기능을 구현했고, ③수정, 삭제 부분은 추가적인 작업이 필요하다.
오늘 한 일들 중 ②,③,⑥ 번에 대해서 조금 설명하고 추가적으로 새로 배운 부분에 대해 적어보려고 한다.
해결한 일
② 댓글 최신순서로 띄우기, 댓글 작성시 맨 위에 뜨게 하기(시간순 정렬)
우선, 소감부터 말해보자면 ②번 기능을 구현한 게 오늘 한 일 중 제일 뿌듯하다. 오늘 뿐 아니라 이번 일주일 중 제일 뿌듯한 일인 것 같다.
먼저, 어제 완료한 부분은 댓글이 웹 상에 띄워지도록 만들어 놨는데 댓글을 추가하게 되면 보통 가장 맨 위에 뜨거나 랜덤으로 아무 자리에나 들어가는 문제가 있었다. 이 부분에 대해서 많은 생각을 해봤는데 아무래도 firebase에 저장해 둔 데이터가 무작위적으로 나와 발생하는 문제인 것 같았다.
그래서 처음에는 firebase의 데이터 순서에 접근해보려고 많이 노력했던 것 같다. 하지만 결국 저장된 데이터의 순서를 가져올 수 없었다.(아마 데이터의 순서가 없을지도)
그래서 해 본 방식이 데이터의 순서를 인위적으로 정해주자! 였다.
먼저 데이터가 어떤 방식으로 나오는지 알아보기 위해 console.log를 여러 곳에 여러 방식으로 찍으며 확인했다.
먼저 데이터가 가장 먼저 마중나오는 부분인 docs부터 콘솔을 찍어봤다.
const docs = await getDocs(collection(db, "comment"));
console.log(docs)
그 결과 이와 같은 객체가 나온다. 그런데 객체 안에 들어있는 내용을 구석구석 찾아봐도 내가 집어넣은 데이터가 보이지 않는다. 절망스러웠다...
하지만 절망하긴 일렀다. 데이터를 꺼내오는 과정에서 docs를 forEach해서 element값을 사용했기 때문이었다.
바로 docs의 element인 doc을 콘솔로 찍어봤다. 추가적으로 doc의 data()도 찍어봤다.
docs.forEach((doc)=>{
console.log("doc=>",doc);
const data = doc.data();
console.log("data=>",data);
});
doc에는 안나오지만 분명 doc.data()에는 내가 넣어놓은 데이터가 보인다!!!!
이로써 docs를 forEach로 돌린 element.data()에는 내가 필요한 부분이 객체 형태로 있다는 것을 알게 되었다.
이 데이터를 이용해 어떻게 시간순서로 정렬하지 싶다가 번뜩!하고 생각이 났다.
현재 forEach안에서 element가 객체 하나씩 나오고 있기 때문에 이 객체를 하나의 배열 안에 넣어놓고 정렬을 하면 되겠구나 싶었다.
let dataArr = [];
const docs = await getDocs(collection(db, "comment"));
docs.forEach((doc)=>{
const data = doc.data();
dataArr.push(data);
})
dataArr.sort((a,b)=> new Date(b.date) - new Date(a.date))
console.log(dataArr)
따라서 새로운 배열에 각각의 객체를 element로 담아주고 시간 순서로 정렬해주었다. 이렇게 정리해놓고 이 새로운 배열을 forEach를 돌려 웹에 구현한다면 정렬한 순서대로 데이터가 나올 것이기 때문이었다.
정렬에 대해 간단하게 설명하자면 알고리즘 문제를 풀며 sort에 대해 공부한 적이 있다. 그 때 잠깐 객체를 element로 갖고 있는 배열에서는 객체의 value값에 따라 정렬을 실행할 수 있다고 했었는데 그게 딱 떠올랐다. 그래서 위와 같은 식을 쓸 수 있었다.
(이 생각이 들었기 때문에 앞서 각각의 객체들을 배열로 넣어주었다)
(sort함수에 대해서는 이 tistory 곳곳에 많은 설명을 해두었기 때문에 생략하겠다)
결국, 정렬한 데이터를 통해 최신순으로 데이터를 리턴할 수 있었다.
dataArr.forEach((detail)=>{
const $commentBox = document.createElement("div");
$commentBox.className = "commentBox";
$commentBox.innerHTML = `
작성자: ${detail.id}
<br>
댓글 : ${detail.comment}
<br>
작성시간 : ${detail.date}`;
// 수정, 삭제 버튼 추가
if (detail["id"] === localStorage.getItem("userName")) {
const $temp = document.createElement("div");
$temp.innerHTML = `
<button id ="editBtn">수정</button>
<button id="deleteBtn">삭제</button>
`;
$temp.children[0].addEventListener("click", editComment);
$temp.children[1].addEventListener("click", deleteComment);
$commentBox.append($temp);
}
$commentList.appendChild($commentBox);
// 중략...
③ 수정, 삭제버튼 추가하기
수정, 삭제 버튼은 만드는데 엄청 쉬웠지만 다른 코드들을 건들다보니 고장났다...
비밀번호를 정확히 입력했음에도 불구하고 비밀번호를 묻는 alert창이 계속해서 나왔다.
언제나처럼 콘솔을 찍어보며 문제를 찾았다.
기존에는 댓글카드를 createElement로 div를 만든 후에 속성값을 부여하고 document.querySelectorAll("속성")을 이용해 지정해 준 뒤 forEach를 이용해 각각의 div박스에 addEventListner를 달았다.
그런데 콘솔을 찍어보니 각각의 div에 eventListener가 중복되서 여러개씩 달려 있다는 것을 알게되었다. 그렇게 되다보니 계속해서 alert 창을 띄우는 것이었다.
따라서 이런식으로 이벤트리스너를 다는 것이 아니라 div를 만듦과 동시에 children을 이용해서 eventListener를 달아주었다.
이렇게 카드에 직접적으로 한 개에 하나씩만 div를 달아주니 문제없이 eventListener가 잘 작동했다.
if (detail["id"] === localStorage.getItem("userName")) {
const $temp = document.createElement("div");
$temp.innerHTML = `
<button id ="editBtn">수정</button>
<button id="deleteBtn">삭제</button>
`;
$temp.children[0].addEventListener("click", editComment);
$temp.children[1].addEventListener("click", deleteComment);
$commentBox.append($temp);
}
$commentList.appendChild($commentBox);
div 박스를 생성하면서 만든 temp라는 div에 button 두 개를 넣어줬기 때문에 temp.chidren[0], [1]를 이용해 넣어주었다.
⑥ 페이지가 로드되면 firebase의 내용을 전부 꺼내고 시작하게 만들기
처음에는 생성해 둔 div를 모두 document.querySelector("#aaa").style.display = "none" 값을 통해 없애려고 했지만, 데이터가 들어간 div만 document.querySelector("#aaa").innerHTML = ""을 이용해서 div 안의 값을 모두 지웠다.
(div안의 값을 모두 지우고 새로 업데이트 하는 방식)
배운 것들
- createElement 삽입은 append로 할 수 있다.
- 생성한 div에 class 속성 값 넣기 : className
- append는 jQuery 메서드로 생각할 수 있는데 js 메서드도 똑같이 있다.
- 이와 비슷하게 js메서드 innerHTML은 jQuery html메서드와 같다.
- document.querySelector("").remove();는 삭제하는 메서드이다.
- confirm메서드를 사용하면 yes or no팝업을 띄우게 된다.
- 로드 될 때 => window.onload
- const a = event.target.parentElement 로 할당하면 a가 이벤트가 실행되는 태그의 상위 태그로 지정된다.
내일 할 일
- 수정/ 삭제 버튼에 local storage만 넣어놨는데 firebase도 수정/ 삭제 하게 만들어서 게시글 유지하기.
- 영화별로 다른 댓글이 올려지도록 구현하기.
- 그동안 못 들었던 강의 듣기
'TIL' 카테고리의 다른 글
2023_10_26 TIL (1) | 2023.10.30 |
---|---|
2023_10_27 TIL (0) | 2023.10.30 |
2023_10_24 TIL (1) | 2023.10.25 |
2023_10_23 TIL (0) | 2023.10.23 |
2023_10_20 TIL (0) | 2023.10.23 |