> For the complete documentation index, see [llms.txt](https://simian114.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simian114.gitbook.io/blog/undefined/blackcoffeestudy/zzz/1.md).

# 1주차

## todo app에서 사용할 조각들

1. localStorage
   * DB로 사용한다.
2. MVC
   * model
   * view
   * controller

## localStorage 를 DB로 사용하기

### DB 라는 새로운 클래스를 만들어서 localStorage 를 감싸고, db로서 사용하는 방법은 어떨까

[MDN localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)

[localStorage 에는 객체가 저장이 안되네..? ---> 문자열만 저장된다!!](https://stackoverflow.com/questions/2010892/storing-objects-in-html5-localstorage)

localStorage에 무엇을 어떻게 저장할 것인가?

### 사용할 수 있는 메서드

<https://developer.mozilla.org/en-US/docs/Web/API/Storage>

1. <https://developer.mozilla.org/en-US/docs/Web/API/Storage/getItem>
   * 등록된 아이템을 `키` 값을 이용해서 찾는다.
   * 만약 아무것도 없을시에는 `null` 을 리턴한다.
2. [setItem](https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem)
   * 아이템을 등록한다.
3. [removeItem](https://developer.mozilla.org/en-US/docs/Web/API/Storage/removeItem)
   * 인자로 받은 키를 이용해 아이템을 찾고, 삭제한다.
4. [clear](https://developer.mozilla.org/en-US/docs/Web/API/Storage/clear)
5. [key](https://developer.mozilla.org/en-US/docs/Web/API/Storage/key)

### localStorage 에는 문자열만 저장할 수 있다.

`localStorage` 에는 기본적으로 **문자열만 저장이 가능하다.** 따라서 객체나 배열등을 저장할 때는 아래의 메서드를 이용해서 먼저 변환 해야한다.

1. `JSON.stringfy`
   * Javascript 값이나 객체를 JSON 문자열로 변환한다.
2. `JSON.parse`
   * JSON 문자열의 구문을 분석하고 그 결과에서 Javascript 값이나 객체를 생성한다.

## MVC 모델 구체적인 계획

## MODEL

* 모든 비즈니스 로직을 처리한다.
* `todo` 아이템이 어디서 관리되어야할까?
* 하나하나 아이템이 **배열의 형태로 관리 되어야 할텐데, 이 데이터들을 어디에 보관해야 좋은걸까?**
* `todo item` 저장하는 방법
  * `todo list` 배열을 만들어서 관리한다.
  * `localStorage` 를 이용해서 DB 이 `localStorage` 를 DB로 사용한다.

### 흠... DB는 결국 만들어야한다. 그리고 새로운 걸 학습한다는 마음으로 localStorage 를 DB로 사용하자.

[MDN localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API)

[localStorage 에는 객체가 저장이 안되네..? ---> 문자열만 저장된다!!](https://stackoverflow.com/questions/2010892/storing-objects-in-html5-localstorage)

## VIEW

* 화면에 렌더링 하는 부분을 다룬다.
* `addEventListener` 은 이 view 에서 다루게 된다.
* 다만 실제로 addEventListener을 하는 곳은 controller 에서 bind 등의 메서드를 통해 진행하게 만든다.
  * `controller` 에서 `setEventListener` 메서드를 만들고 인자들을 건네주면 해당 메서드에서 처리하는 방식으로 하면 된다. 아래 링크를 참고하자.
    * [TODO MVC VIEW](https://github.com/tastejs/todomvc/blob/gh-pages/examples/vanillajs/js/view.js)
    * [TODO MVC CONTROLLER](https://github.com/tastejs/todomvc/blob/gh-pages/examples/vanillajs/js/controller.js)
  * 여기서 의문이 드는 것은 **왜 view 의 요소에 addEventListener 를 하는데 setEventListener 은 view 가 아닌 controller 에서 하는거지?**
    * 이유는 간단하다. 실제 사용자와 실제 사용자의 요청이 처음 당도하는 곳은 **controller** 이다.
    * 그리고 사용자의 요청에 따라 각 요청에 맞춰 무언가를 호출하는 곳도 controller 이다.
    * 즉 **controller 에 함수가 각 이벤트에 맞는 함수가 존재를 만들어야지만 view 에 이 controller 에 있는 함수를 콜백으로 등록할 수 있기 때문**

#### 사용자가 todo 리스트에 todo 를 추가한다고 하자 이 때 어떻게 동작이 이뤄져야 하는가?

1. todo 를 추가한다면, 해당하는 event 가 발생할 것이다.
   1. `+` 버튼을 누르거나 `enter` 키보드를 누르는 행위
2. 사용자로부터 요청이 들어왔으므로 우리는 **Controller** 에서 해당 요청을 핸들링한다. 지금의 예시는 `add` 를 하는 동작이므로 **controller 의 addTodoItem** 메서드를 호출하자.
3. `addTodoItem` 이 어떤 역할을 하는지 생각해보자
   1. `TodoList` 에 새로운 `li` 를 추가한다.
      * 이 역할은 **view** 에 맡긴다.
   2. 관리되고 있는 `TodoList`  배열에 `todo` 를 하나 추가한다
      * **model** 에 맡긴다.
4. **그런데 잠깐. 사용자로부터 add 요청이 들어온걸 컨트롤러는 어떻게 알아차린거지?**
   * 이 부분이 핵심이다. **Controller** 는 **어떻게** 사용자로부터 요청이 들어왔다는 걸 알 수 있을까?
   * 당연하게도 **addEventListener** 을 했기 때문이다. 하지만 **우리는 아직 addEventListener** 을 등록하지 않았다. 어서 등록하러 가자.
   * **Controller 은 DOM 을 관리하지 않잖아? 그런데 어떻게 addEventListener 을 하는거야?**
     * 말 그대로 **Controller는 정말 사용자의 요청을 요청에 맞게 이리 보내고 저리 보내는 컨트롤의 역할만 해야한다.** 그리고 **DOM의 관리는 view 에게 맡긴다.**
     * **따라서 우리는 addEventListener을  View 에다 해줘야한다.**
   * **addEventListener**을 하자.
     * **Controller** 는 view 와 model 에 사용자의 요청을 넘겨줘야 하므로 **자신의 속성으로 view와 model 을 갖고 있다.**
     * 따라서 **Controller** 가 처음에 생성될 때 즉 **constructor** 메서드를 호출할 때 `this.view` 을 활용해서 `addEventListener` 를 해야한다.
     * 여기서 명심할 건 곧장 `addEventListener` 를 하는게 아닌 `setEventListener` 를 호출하고 이 호출의 결과로 `addEventListener` 은 `view` 내부에서 진행돼야한다는 것.
5. **4번의 setEventListener의 내부에서 호출하는 메서드는 Controller 의 addTodoItem 이다!!!**
6. `addTodoItem` 호출의 결과로
   1. `model` 이 관리하는 `item-list` 에 하나의 `todo` 가 추가된다.
   2. `model` 에 추가 되는 순간 페이지에 보이는 list도 추가된다.
      * 2번은 1번의 성공 이후에 적용되어야 하므로 **콜백으로 넣어 주는 걸 잊지 말자.**

## CONTROLLER

* 컨트롤러는 사용자와 직접 대면하는 곳이다.&#x20;
* 따라서 모든 것의 시작은 여기 controller 에서 시작된다. 사용자가 어떤 동작을 하던 controller 을 거치고 컨트롤러는 이후에 model과 view로 작업을 넘긴다.

#### 컨트롤러에 있어야 하는 메서드들을 나열해보자

1. `showAll` - view
   * 처음 페이지에 접속했을 때 또는 `show all` 탭을 클릭하면 실행됨
2. `showCompleted` - view
   * `show completed` 탭을 클릭하면 실행됨
3. `showNotCompleted` view
   * `show not completed` 탭을 클릭하면 실행됨
4. `addItem` - model, view
   * `todo` 아이템의 개수를 `count` 한다.
   * 키보드 엔터를 눌렀을 때 실행됨
5. `removeItem` - model, view
6. `x` 버튼을 클릭했을 때 실행됨
7. `editItem` - view(포커스만 되게)
   * `todo` 를 더블 클릭했을 때 실행됨
8. `editItemCancel` - view (그냥 간단히 focus 만 풀리게)
   * `editItem` 인 상황에서 `ESC` 를 눌렀을 때 실행됨
9. `editItemSave` - model, view
   * `editItem` 인 상황에서 `ENTER` 를 눌렀을 때 실행됨
10. `checkItemComplete` - view, model
    * 체크 버튼을 눌렀을 때 실행됨
