Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2주차 기본 과제] 가계부 #7

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open

[2주차 기본 과제] 가계부 #7

wants to merge 19 commits into from

Conversation

urjimyu
Copy link
Contributor

@urjimyu urjimyu commented Oct 27, 2023

✨ 구현 기능 명세

  • 기본 과제
    ✅ 1. 최초 데이터
    1. 상수로 INIT_BALANCE, HISTORY_LIST 데이터를 가집니다. (상수명은 자유)

      • INIT_BALANCE = 0
      • HISTORY_LIST : 입출금 내역 리스트 (4개)
    2. 최초 실행시 위 상수 데이터들 이용해 렌더링합니다. (즉, html에 직접 박아놓는 하드코딩 ❌)

      → 나의 자산은 INIT_BALANCE로부터 4개의 입출금 내역 리스트를 반영하여 보여줍니다.

✅ 2. 총수입 / 총지출
1. 마찬가지로 최초에 HISTORY_LIST에 있는 수입 내역과 지출 내역을 계산해서 총수입, 총지출을 보여줍니다.

✅ 3. 수입/지출 필터링
1. 수입, 지출 선택에 따라 내역 리스트가 필터링됩니다.

✅ 4. 리스트 삭제
1. 각 리스트의 X 버튼을 누르면 해당 리스트가 삭제됩니다.
2. 리스트 삭제시 나의 자산에 반영됩니다.
3. 리스트 삭제시 총 수입 / 총 지출에 반영됩니다.

✅ 5. 리스트 추가

> 하단 footer의 `+` 버튼을 누르면 리스트 추가 모달이 나타납니다.
> 
1. `수입` `지출`  버튼
    - default ⇒ 수입
    - 하나를 선택하면 다른 항목은 자동으로 선택이 풀립니다.
2. `카테고리`를 선택
    - `수입`을 선택하면 수입 관련된 항목들이, `지출`을 선택하면 종류에 지출 관련된 항목들이 나옵니다.
    - 카테고리는 수입, 지출 각각 2개 이상씩 있습니다.
3. `금액`과 `내용` 입력 input
4. `저장하기` 버튼
    - 저장하기 버튼 클릭시 입력한 내용들로 이뤄진 리스트가 추가됩니다.
    - 이에 따라 나의 자산(잔액), 총수입, 총지출도 알맞게 변경됩니다.
    - 저장 성공시 alert 메시지를 띄웁니다.
    - 저장하기를 눌러도 모달이 닫히지 않습니다.
5. `닫기` 버튼
    - 클릭하면 모달이 사라집니다.

💎 PR Point

1 . 상수 파일로 수입/지출 각각의 카테고리 분리, 각 상세 내역 리스트를 분리해서 js를 활용해 렌더링하고자 했습니다.
2. 상수 파일을 돌면서 리스트 내역을 업데이트 하는 함수, 잔액과 지출/수입 내역을 업데이트 함수, 새로운 리스트 항목이 추가되면 새롭게 업데이트 하는 함수 등 최대한 함수 재사용을 시도해봤습니다.


🥺 소요 시간, 어려웠던 점

  • 4h
  • 함수를 적절하게 분리해서 리스트의 변동 사항을 잔액과 각각의 수입/지출 값에 반영하는 것이 까다로웠습니다.

🌈 구현 결과물

노션 링크

@urjimyu urjimyu self-assigned this Oct 27, 2023
Copy link

@imeureka imeureka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생해쓔 언니 정말 모듈화? 상수화 야무지게 잘 했다... 구조를 위해 고민한 흔적들이 넘 잘 보여서 좋았습니당.

const deleteButton = $$(".delete_button");
const listContainer = $(".list-container");

HISTORY_LIST.forEach((history, index) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기능적으론 완벽한 코드지만 더 성능 개선을 위해서 미뇽이 document.createElement 찾아보다가
DocumentFragment에 대해 알게 됐어!!

  • const fragment = document.createDocumentFragment(); 를 이용하면
    현재는 생성되는 즉시 li에 추가되는데 . listContainer 이로 인해 매번 리플로우가 발생하여 HISTORY_LIST어레이가 큰 경우 성능에 영향을 미칠 수 있다네용
    🌟이 때 DocumentFragment
    메인 DOM의 조작(manipulation)이 필요할때 페이지 reflow 등 성능적 영향을 최소한으로 줄이기 위해 사용된다하니 참고쓰,,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 유용한 피드백 감사합니다,,🫶

const spanCategory = document.createElement("span");
spanCategory.className = "list__category";
spanCategory.textContent = category;
listItem.appendChild(spanCategory);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 개인적으로 궁금한 appendappendChild 쓰는 기준..?이 인나요 OB사마

Copy link
Contributor Author

@urjimyu urjimyu Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 제대로 차이를 알고 쓰지 않았었는데 이번 기회에 저도 정확한 차이를 알게 되었네요! 넘 고마운 질문,,✨
정리하자면,,

append는 여러 값을 추가할 수 있고 문자열(DOMString)도 추가가 가능하며 반환값이 없습니다.
반면 appendChild는 문자열과 다중 값 추가가 불가능하고 반환값(추가된 노드 객체 반환)이 있습니다.

appendChild vs append
차이가 표로 정리가 잘 되어 있는 자료

//모달 닫기
const closeButton = $(".close");
closeButton.addEventListener("click", () => {
addModal.classList.remove("open");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 맞아 스타일 속성 바꾸는 것 말고도 remove 속성이 있었다는 것...🌟

amountValue = amountValue.replace(/,/g, "");

// 숫자가 아닌 값이 입력되었는지 검사
if (isNaN(Number(amountValue))) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와 유효성 검사까지 너무 갓갓 지민이네요..🌟

updateCategoryOptions();
});

modalExpenseCheckbox.addEventListener("change", () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

똑같은 코드 발견!! 두개 다 선택 가능하도록 인 코드 같습니당!!

minusAmount += amount;
}
});
function updateNewHistory() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오잉 혹시 아래처럼 밖에 두는거랑 함수안에 초기화 하고
updateHistoryList(); updateAmounts();
두개 호출하는 이유가 있나요?.?

Copy link
Member

@Rose-my Rose-my left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

역시나 배울점이 정말 많았던 코드입니다❤️ ID랑 클래스도 야무지게 잘 써줘서 공부가 되었어요 저도 아이디를 적극 활용해보려고요! 정말 수고했어요⭐️😊

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

category도 따로 상수처리를 할 생각은 전혀 못했는데!! 역시⭐️

<section>
<header class="details-container">
<div class="date-container">
<button type="button">&lt;</button>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아차차 HTML 특수문자 처리.....습관적으로 그냥 썼는데 리팩토링때 명심해야겠어요

incomeCheckbox.addEventListener("change", () => {
if (incomeCheckbox.checked) {
incomeItems.forEach((item) => {
item.parentNode.style.display = "flex";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

따로 함수선언하지 않고 parentNode.style.display 로 간편하게 설정하는 방법도 있었군요!

height: 60%;
}

@keyframes animation-modal {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

처음보는 css발견! keyframes 너무 신기하네요 잘 배웠어요

const amount = history.amount;
const type = history.type;

if (type === "수입") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type을 지정해주니까 훨씬 코드가 간결해졌네요!

addModal.classList.remove("open");
});

// 모달 숫자 입력 시 콤마 찍히도록
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toLocaleString()을 한번 사용해보세요! 첫 단위로 콤마를 찍어주는 아주 간편한 방법이 있답니당
블로그참고


// 상수 파일에서 내역 불러와서 띄워주기
function updateHistoryList() {
HISTORY_LIST.forEach((history, index) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 HISTORY_LIST자체도 상수로 const historyList = HISTORY_LIST; 이렇게 처리했어요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants