[노마드코더-바닐라 JS로 크롬 앱 만들기]todo.js (3)

2021. 1. 25. 18:13Projects/VanilaJS- To-Do 앱 만들기

728x90
반응형

To-do list를 지우기 위해서는 2가지를 해야 한다.

1) local storage에서 todo 하나를 지워야 하고 그리고 저장해야 한다.

2) 그리고 HTML 에서도 지워야 한다.

 

먼저 HTML을 먼저 지우는 것부터 하겠다.

우리는 li를 지울 것이다.

그러기 위해서 함수를 하나 만든다. deleteToDo라는 함수 만들기

function deleteToDo(event){

 

}
delBtn.addEventListener("click",deleteToDo);

paintToDo 함수에서, delBtn(삭제버튼)을 눌렀을 때 deleteToDo 함수가 실행되도록 addEventListener를 사용한다.

 

function deleteToDo(event){

    console.log(event);

}

console.log로 event를 출력해보면

이 상태에서는 버튼이 클릭되었다는 것은 알지만 어떤 버튼이 클릭되었는지를 모른다. 우리는 어떤 버튼이 클릭되었는지를 알아야 어떤 걸 지울 수 있는지 알 수 있다.

 

function deleteToDo(event){

    console.log(event.target);

}

그래서 .target 프로퍼티를 이용한다. (이벤트 타겟이란 이벤트를 유발시킨 객체(태그)를 알 수 있는 프로퍼티임)

근데 우리는 우리가 누른 삭제 버튼이 포함된 li 전체가 지워져야 하므로 부모를 알아내야 한다. (버튼의 부모를 알아내야 함)

 

function deleteToDo(event){

    console.log(event.target.parentNode);

}

이렇게 parentNode프로퍼티를 이용해서 부모노드를 알아낼 수 있다.(parentElement랑 비슷한듯)

실행하면 제대로 그 버튼의 부모를 알아낸 것을 볼 수가 있다.

 

function deleteToDo(event){

    const btn = event.target;

    const li = btn.parentNode;

 

    toDoList.removeChild(li);

}

removeChild 메소드를 이용하여 다음과 같이 코드를 작성하면 delBtn을 눌렀을 때 li항목이 삭제되는 것을 볼 수 있다.

(부모.removeChild(떼어내려고 하는 자식객체) )

하지만 이 상태에서는 새로고침하면 toDoList에서 삭제가 안되고 그대로 뜬다.

그래서, 이럴 때 toDos와 함게 다른 동작을 하는 니콜라스가 진짜 좋아하는 functional programming이 있다!

이제 할 것은, ‘to do’를 깨끗하게 하는 것을 만들 것이다.

 

function filterFn(toDo){

    return toDo.id === 1

}

 

function deleteToDo(event){

    const btn = event.target;

    const li = btn.parentNode;

 

    toDoList.removeChild(li);

 

    const cleanToDos = toDos.filter(filterFn)

}

여기서 filter는 함수 하나를 실행시킬 것이다. 그 함수이름을 filterFn이라고 정의한다. 이 filter는 마치 forEach에서 function을 실행하는 것 같이 각각의 item들에게 실행이 될 것이다.

그래서 이 filter가 하는 것은, true인 아이템들을 반환하여 새로운 array를 하나 만들 것이다.

예를 들어 위의 코드는 임시로 toDo(각 배열의 element에 해당)의 id가 1인 것만 필터링되어 새로운 배열이 만들어져서 그것을 cleanToDos 라는 이름의 배열로 저장되는 코드인 것이다.

(*filter: array안에 있는 모든 요소들을 가지고 함수를 실행하고, true인 것들만 return하여 새로운 배열을 만들어내는 메소드)

 

function deleteToDo(event){

    const btn = event.target;

    const li = btn.parentNode;

 

    toDoList.removeChild(li);

 

    const cleanToDos = toDos.filter(function(toDo){

        console.log("toDo.id는 "+toDo.id+"  li.id는 "+li.id);

        console.log(toDo.id,li.id)

        return toDo.id !== li.id

    });

    console.log(cleanToDos);

}

 

li에 없는 id인 toDos를 체크하고 싶다.

그런데 주의해야할 것은 toDos의 id는 숫자고, li의 id는 String이라는 것에 유의한다.

위의 코드를 실행시켜 보면 (3개의 항목 중 1번째 항목을 클릭해서 지웠음)

 

이렇게 뜨는 것을 볼 수가 있는데 “1” 라고 뜨는 것으로 보아 li의 id는 String이다. 그러므로 parseInt를 이용하여 고쳐준다.

 

 

function deleteToDo(event){

    const btn = event.target;

    const li = btn.parentNode;

 

    toDoList.removeChild(li);

 

    const cleanToDos = toDos.filter(function(toDo){

        console.log("toDo.id는 "+toDo.id+"  li.id는 "+li.id);

        return toDo.id !== parseInt(li.id)

    });

    console.log(cleanToDos);

}

 

여기서 첫번째 항목을 지우면 (밥먹기 옆에있는 delBtn을 클릭하면 그 버튼의 부모인 li가 지워진다. (그러므로 li.id == 1)그리고 cleanToDos는 toDos에 대한 filter 메소드를 실행하는데, toDo의 id와 parseInt(li.id)의 값이 다르면 cleanToDos에 저장이 된다.

 

이제 cleanToDos는 2개 이고 toDos는 3개 이다.

이제 할 것은 toDos를 교체하면 된다.

 

 toDos = cleanToDos;

 

그런데 문제는 지금 상태에서는 이렇게 코딩할 수 없다. 왜냐하면 toDos가 const타입이기 때문, toDos를 let으로 바꿔준다.

 

let toDos = [];

이렇게 바꾸고 나면 잘 동작한다.

 

 

toDos = cleanToDos;

saveToDos();

그리고 saveToDos()를 호출하면 저장까지 되므로 새로고침을 해도 local storage에 저장이 되어있으므로 삭제가 반영되어 보여진다.

 

function deleteToDo(event){

    const btn = event.target;

    const li = btn.parentNode;

 

    toDoList.removeChild(li);

 

    const cleanToDos = toDos.filter(function(toDo){

        return toDo.id !== parseInt(li.id)

    });

 

    toDos = cleanToDos;

    saveToDos();

 

}

(그래서 총 완성된 deleteToDo 함수의 모습)

728x90
반응형