본문 바로가기

TIL

[TIL-49] 노마드코더 크롬앱(JS) 클론코딩 #7.6~#7.8

#7 To-do 리스트

ToDo 삭제하기

  • todo 지울 때 로컬스토리지도 업데이트해야 함.
    • 로컬스토리지는 데이터베이스 아님. toDos 배열이 데이터베이스. 배열의 아이템을 지워야 함.
    • 같은 아이템이 두 개일수도 있음. 뭘 지웠는지 구분할 수 있어야 함.
  • [나] 삭제된 리스트 태그의 자식 번호를 구해서 해당 인덱스의 toDos 배열 아이템을 삭제하고 로컬스토리지에 업데이트 함. 
    • [참고] 배열에서 특정값 삭제하기 https://hianna.tistory.com/489
    • function deleteToDo(event) {
        const li = event.target.parentElement;
        li.remove();
        toDos.splice(li.childElementCount, 1);
        console.log(li.childElementCount, toDos);
        saveToDo();
      }
    • [문제] 처음에는 잘 작동하는데 그 다음부터는 배열에서 삭제되는 부분이 안 맞음.
  • [니꼬] toDos 배열의 각 아이템에 아이디를 줌. 즉, 배열 안에 그냥 텍스트 대신 아이디와 todo를 담은 객체를 만듦.
    • 랜덤 id 만들기
      • element가 만들어질 때 Date.now() 함수를 이용해서 숫자 부여.
    • toDos 배열에 그냥 newTodo 대신 object 푸시함.
      • const newTodoObj = {
            text: newTodo,
            id: Date.now(),
          };
          toDos.push(newTodoObj);
    • id를 사용하려면 html에 둬야 함.
      • paintToDo에 텍스트인 newTodo가 아니라 객체인 newTodoObj 추가.
      • paintToDo에서 newTodo 그대로가 아니라 newTodoObj.text를 span에 넣는 것으로 바꿈.
      • paintToDo에서 만든 <li>에 아이디를 부여함.
        • li.id = newTodoObj.id;
    • 배열에서 아이템(여기선 객체) 삭제하기
      • 실제로 배열에서 그걸 지우는 게 아니라, 지우고 싶은 item을 빼고 새로운 배열을 만듦. 즉, item을 지우는 게 아니라 그 item을 제외함.
      • 그래서 filter 함수 사용.
        • forEach와 비슷. filter는 실행할 어떤 함수를 부르고, 배열의 각 아이템에 대해 차례대로 실행함.
        • 그런데 filter가 부른 함수는 반드시 true를 리턴해야 함. 새로운 배열에도 그 아이템을 포함하고 싶으면. false를 리턴하면 그 아이템은 포함되지 않음.
        • [나] forEach로 toDos 배열의 각 객체가 가진 아이디 비교해보려고 애썼는데 filter가 필요한 거였음.
          • toDos.forEach(if(toDos.id === li.id) { 그 객체 삭제! })
      • filter 사용해서 나온 배열은 새로운 배열이기 때문에 toDos 배열로 업데이트해줘야 함.
        • let toDos = [];
        • toDos = toDos.filter((item) => item.id !== li.id);
          • [문제] 적용이 되질 않음!!
            • id는 숫자. 하지만 li.id는 string!!!! 
            • 내가 잘못해서 그런 줄 알고 몇 십분을 쳐다봤는데 어차피 해결 못할 문제였음...!
            • parseInt(li.id) : 문자열을 숫자로 바꿔줌.
      • 마지막으로 toDos를 로컬스토리지로 업데이트!!
        • saveToDos();
        • [나] 처음엔 당연히 saveToDo로 마무리했는데...
          • 작업한 deleteToDo 함수는 paintToDo 함수 안에서 (버튼에) 사용됐고, paintToDo 함수는 handleTodoSubmit 함수 안에 사용됐으니, handleTodoSubmit 안의 paintToDo 다음에 saveToDo가 실행되니까 필요 없는 줄 알았음.