# Part4

## 1.Backbone.Router

* `routers` 를 사용하지 않고도 앱을 만들수있다.
* 하지만 앱에서 특정한 상태(`state`) 를 만들고 싶거나, 앱의 특정 위치(`location`)으로 이동하고 싶다면 `reference`(link/ URL)가 반드시 필요하다.
* ROUTER는 바로 이런 경우에 사용한다.
* 보통의 JS앱은 라우팅을 `hash-tag`를 이용해서 구현한다.
  * `GMAIL`에 접속후 URL을 유심히 살펴보자.
* `backbone`에서는 이 URL 패턴과 함수를 매칭 시킨다.
  * Rasil에서 했던것처럼 인자를 넘길 수 있다.
* 기본적인 구조는 ***`'route' : 'mappedFunction'`***
  * `'route'` 에 ***\`*****\`\*** 가 있다면 모든 URL이 여기로 들어온다는 뜻이다.
  * 아래 예시를 보면 ***\`'*****filter' : 'setFilter'\`\*** 가 있는데
    * `~~#this/is/test/haha` 와 같이 들어오면 # 뒤에 오는 모든 값들이 인자가 된다.
    * `setFilter` 함수의 인자로 `this/is/test/haha`가 모두 들어가게 된다는 것.

### 1.1 Initializing the Router

* ```javascript
  app.Router = Backbone.Router.extend({
    routes: {
      '*filter' : 'setFilter'
    },
    setFilter: function(params) {
      console.log('app.router.params = ' + params); // just for didactical purposes.
      window.filter = params.trim() || '';
      app.todoList.trigger('reset');
    }
  });

  //--------------
  // Initializers
  //--------------

  app.router = new app.Router();
  Backbone.history.start();
  app.appView = new app.AppView();
  ```
  * 라우터 클래스를 만들고 사용하기 위해서는 먼저 초기화를 시키자
    * 이렇게 한 이후 `URL`의 마지막에 `#This/is/Test` 와 같이 입력을 해보자.
    * 입력된 모든 데이터가 `params`의 형태로 입력되고 콘솔로 출력된다.
  * `setFilter`
    * 이 함수는 최종적으로 `app.todoList.trigger('reset');`를 실행한다
    * `todoList`에 걸어놓은 `event` 인 `addAll` 이 실행된다.
    * 여기서 굳이 왜..? `window.filter` 를 선언하는 걸까?
      * `addAll` 함수에서 사용한다.
      * `fileter` 라는 데이터를 `window` 의 프로퍼티로 만들면 전역함수로 만드는 것과 동일한 효과를 내므로 어디서든 사용할 수 있게 된다.

### 1.2. Processing the routes

* 현재 예시에서는 주소창에 `#아무거나` 로 앱을 호출하면 무조건 `setFilter` 함수가 호출되고 이는 무조건 `addAll`을 호출한다. (라우팅 주소로 `pending` 과 `completed` 를 보내면 아직은 안된다.)
* ```javascript
  addAll: function(){
    this.$('#todo-list').html(''); // clean the todo list
    // filter todo item list
    switch(window.filter){
      case 'pending':
        _.each(app.todoList.remaining(), this.addOne);
        break;
      case 'completed':
        _.each(app.todoList.completed(), this.addOne);
        break;
      default:
        app.todoList.each(this.addOne, this);
        break;
    }
  }
  ```
* 주소창 입력으로 들어온 값에 따라 다른 함수가 실행이 된다.
  * 기본적으로는 반복을 돌면서 `li` 태그를 만들어 낸다.
    * 완료된 `todo` 완료되지 않은 `todo` 모두가 출력되는 것.
  * `pending`으로 들어오면 아직 완료되지 않은 `todo` 들만 출력이 된다.
  * `completed`로 들어오면 완료된 `todo` 들만 보인다.

#### remaining(), completed()

* 이 두 함수들은 `model`의 `completed` 속성의 `true`, `false` 속성에 따라 값이 결정된다.
* | Completed?  | True  | False |
  | ----------- | ----- | ----- |
  | remaining() | false | true  |
  | completed() | true  | false |

  즉, ***모델*** 에 디펜던시가 있다. 이전에 모델을 관리하도록 만든게 `collection`이라고 했다. `collection` 에다가 관련 메서드를 추가해주자.
* ```javascript
  app.TodoList = Backbone.Collection.extend({
    model: app.Todo,
    localStorage: new Store("backbone-todo"),
    completed: function() {
      return this.filter(function( todo ) {
        return todo.get('completed');
      });
    },
    remaining: function() {
      return this.without.apply( this, this.completed() );
    }
  });
  ```
  * `completed`
    * `return` 문의 뒤쪽부터 읽으면 이해하기가 쉽다.
    * ```javascript
      function( todo ) {
        return todo.get('completed');
      };
      ```
      * 이 익명함수는 인자로 들어온 `todo` 모델에서 `completed` 속성을 return 한다.
      * `completed` 속성은 `true` 또는 `false` 둘 중 하나므로 참 거짓이 return 된다.
    * 이제 `this.filter()` 를 살펴보자.
      * 이 부분은 잘 모르겠다!
  * `remaining`
    * `without` 와 `apply` 메서드를 체이닝해서 `completed` 가 false 인 경우를 리턴한다 라고 이해하자...


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://simian114.gitbook.io/blog/undefined/backbonejs/absolute-beginner/part4.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
