본 캠프/미니 프로젝트

[React 7기] CH 1 미니 프로젝트. (4)

Iruka913 2024. 10. 4. 19:47

방명록에 CRUD 기능이 구현되었다!

CR의 기능이 구현됐으니, UD의 기능을 구현해보자. 

1. 수정 사항을 업데이트 하는 기능에 대해 알아보자. 

// UPDATE 방명록 편집
$(document).on("click", "#editIcon", async function (event) {
  let visitCard = $(event.target.parentElement.parentElement);
  let table = visitCard.find("#table");
  let visitBoxIcon = visitCard.find("#visitIconBox");
  let editForm = visitCard.find("#editForm");
  let writer = table.find(".writer").text();

  table.addClass("hidden");
  visitBoxIcon.addClass("hidden");
  editForm.removeClass("hidden");

  editForm.off("submit").on("submit", async function (event) {
    event.preventDefault();

    let newContent = editForm.find(".newcontent").val();

    let queryRef = collection(db, "visitor");
    let q = query(queryRef, where("writer", "==", writer));
    let querySnapshot = await getDocs(q);

    querySnapshot.forEach(async (d) => {
      await updateDoc(doc(db, "visitor", d.id), {
        content: newContent,
      });
      alert("수정완료!");
      window.location.reload();
    });
  });
});

// 페이지가 로드될 때 방문 기록을 불러옴
$(document).ready(function () {
  loadVisitorLogs();
});

 

코드를 하나하나 해부해볼까?

 

editIcon 버튼을 클릭하면?

 

visitCard에 해당 버튼의 부모의 부모의 요소를 지정한다,. 버튼은 현재 visiticonbox로 한 번 묶여있기 때문에 그 밖의 밖을 한 번 지정해줘야한다. 

 

table에는 visitCard의 table요소를

visitBoxIcon 에는 visitCard의 visitIconBox 요소를.

editForm에는 editForm요소를.

writer에는 writer 클래스의 텍스트를 불러온다. 

 

그리고 그 이후에 table, visitBoxIcon에 hidden 클래스를 부여해서 보이지 않게 만들고. 

editForm에는 hidden 클래스를 지워서 화면에 보이게 만든다. 

 

submit는? form 태그를 제출할 때 발생하는 이벤트로, 폼 데이터를 처리하거나 검증할 때 사용된다. 내가 원래 초기에 만들었던 CR기능에는 click이 사용되었지만, 여기서는 submit 기능이 쓰인 것으로 보인다. 

<button type="submit" class="btn btn-warning" id="visitBtn">

 

이런 식으로 버튼 타입에 submit을 넣으면 form 태그를 넣을 때 유용하게 쓸 수 있다. 

 

 editForm.off("submit").on("submit", async function (event) {

이 부분의 경우, 이벤트의 중복 실행 방지를 위해 이전에 할당된 submit(이 사이트의 경우, 방명록 작성 기능에 쓰였던 이벤트 리스너인 것으로 보인다.)을 지워주고, 새로 할당하기 위한 코드다. 

 

그 후, preventDefault()로 페이지가 새로고침 되지 않도록 방지해야한다.

submit에는 기본적으로 새로고침의 기능이 내장되어 있기 때문에, 이를 막기 위해 넣어야하는 것.

 

    let newContent = editForm.find(".newcontent").val();

그리고 nexcontent 클래스의 밸류값을 찾아 newcontent에 삽입한다. 

    let q = query(queryRef, where("writer", "==", writer));
    let querySnapshot = await getDocs(q);

 

q에다가 writer가 현재 방명록 작성자와 일치하는 문서를 찾는다라는 조건을 설정해주고, getdocs를 통해 조건에 맞는 문서를 firebase에서 가져온다. 

    querySnapshot.forEach(async (d) => {
      await updateDoc(doc(db, "visitor", d.id), {
        content: newContent,
      });
      alert("수정완료!");
      window.location.reload();
    });
  });
});

 

검색된 문서들을  foreach로 순회한다. d는 문서 객체. firebase에서 가져온 하나의 문서에 해당한다. 

d.id를 통해서 각각의 문서에 배정된 고유한 id를 지정할 수 있다. 이를 통해 해당 문서를 업데이트, 삭제할 수 있다. 

 

이렇게 지정이 끝나면 updateDoc를 통해 원래의 필드 content를 newcontent로 업데이트할 수 있다. 

 

2. 방명록을 삭제하는 기능에 대해 알아보자. 

// 방명록 삭제
$(document).ready(function () {
  $(document).on("click", "#deleteIcon", async function (event) {
    let visitCard = $(event.target.parentElement.parentElement);
    let writer = visitCard.find(".writer").text();

    console.log("삭제하려는 작성자:", writer);

    let queryRef = collection(db, "visitor");
    let q = query(queryRef, where("writer", "==", writer));
    let querySnapshot = await getDocs(q);

    console.log("쿼리 결과:", querySnapshot);

    if (!querySnapshot.empty) {
      querySnapshot.forEach(async (d) => {
        await deleteDoc(doc(db, "visitor", d.id));
        console.log("삭제된 문서 ID:", d.id);
        alert("삭제 완료!");
        window.location.reload();
      });
    } else {
      alert("삭제할 방명록을 찾을 수 없습니다.");
    }
  });

  loadVisitorLogs();
});

 

$(document).ready(function () {
  $(document).on("click", "#deleteIcon", async function (event) {
    let visitCard = $(event.target.parentElement.parentElement);
    let writer = visitCard.find(".writer").text();

    console.log("삭제하려는 작성자:", writer);

    let queryRef = collection(db, "visitor");
    let q = query(queryRef, where("writer", "==", writer));
    let querySnapshot = await getDocs(q);

    console.log("쿼리 결과:", querySnapshot);

 

여기서부터 여기까지는 아까와 같다. 어떤 항목이 선택되었는지를 데이터베이스에서 가져오는 과정이다. 

    if (!querySnapshot.empty) {
      querySnapshot.forEach(async (d) => {
        await deleteDoc(doc(db, "visitor", d.id));
        console.log("삭제된 문서 ID:", d.id);
        alert("삭제 완료!");
        window.location.reload();
      });
    } else {
      alert("삭제할 방명록을 찾을 수 없습니다.");
    }
  });

 

이 부분의 경우, if 구문을 넣어서 방명록에 내용이 있으면 등록이 되고, 안 되면 에러 메시지를 표시하는 걸로 바꿨다. 나중에 이 코드는 복습하면서 다시 한 번 써보는 게 좋겠다.