Backbone.jsでRESTful APIの画面を作る


Backbone.jsを使って、RESTful APIからデータを取得して表示する画面をつくります。
[Backbone.jsでModelに対応するViewをつくる](http://qiita.com/ledsun/items/dac6e7595ea9f28d30d2)の複数レコード版です。

# 準備
## 依存ライブラリ
Backbone.jsはjQueryとunderscoreに依存しています。
準備を簡単にするために、各ライブラリをCDNから取得します。

```html
<head>
  <script src="https://code.jquery.com/jquery-2.2.2.js" integrity="sha256-4/zUCqiq0kqxhZIyp4G0Gk+AOtCJsY1TA00k5ClsZYE=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.2/backbone.js"></script>
</head>

```

## RESTful API
[typicode/jsonplaceholder: A simple fake REST API server](https://github.com/typicode/jsonplaceholder)を使います。

```
npm install -g jsonplaceholder
jsonplaceholder
```

http://localhost:3000/posts からリソースを取得します。

# 完成画面
![スクリーンショット 2016-03-29 12.04.58.png](https://qiita-image-store.s3.amazonaws.com/0/15964/158cb613-2339-1bff-2248-c47c13d6ea1a.png "スクリーンショット 2016-03-29 12.04.58.png")



# 実装
## 方針

### Model
一つのレコードに対応するモデルをPostModelとして実装します。

### ModelのView
PostModelから表示するDOMを作るビューをPostViewとして実装します。

### ModelのCollection
RESTful APIから複数のレコードを取得して、PostModelのコレクションを作成するモデルをPostCollectionとして実装します。

### ApplicationのView
PostCollectionの取得したレコードをPostViewを使ってDOMに変換し、表示するビューをAppViewとして実装します。

## ソースコード
```html:index.html
<head>
  <script src="https://code.jquery.com/jquery-2.2.2.js" integrity="sha256-4/zUCqiq0kqxhZIyp4G0Gk+AOtCJsY1TA00k5ClsZYE=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.2/backbone.js"></script>
  <style>
    body {
      font-size: 1.1em;
    }

    input {
      font-size: 100%;
      width: 700px;
    }

    textarea {
      font-size: 100%;
      height: 100px;
      width: 700px
    }

    button {
      font-size: 100%;
    }
  </style>
</head>

<body>
  <script>
    const PostModel = Backbone.Model.extend(),
      PostView = Backbone.View.extend({
        initialize() {
          this.listenTo(this.model, 'change', this.render)
        },
        template(data) {
          return `
            <div>title:</div>
            <input value="${data.title}">
            <div>body:</div>
            <textarea>${data.body}</textarea>
          `
        },
        render() {
          this.$el.html(this.template(this.model.attributes))
          return this
        }
      }),
      PostCollection = Backbone.Collection.extend({
        url: 'http://localhost:3000/posts',
        model: PostModel
      }),
      posts = new PostCollection(),
      AppView = Backbone.View.extend({
        initialize() {
          this.listenTo(posts, 'add', this.render)
          posts.fetch()
        },
        render(post) {
          $('body').append(
            new PostView({
              model: post
            })
            .render()
            .$el
          )
        }
      })

    new AppView
  </script>
</body>
```

### PostModel
```js
PostModel = Backbone.Model.extend()
```
ただEvent Emmiter付きの箱です。
Backbone.Modelはデフォルトで`change`イベントを提供します。
Collectionに指定すると、取得したレコード毎にPostModelのインスタンスを作成してくれます。

### PostView
```js
PostView = Backbone.View.extend({
  initialize() {
    this.listenTo(this.model, 'change', this.render)
  },
  template(data) {
    return `
      <div>title:</div>
      <input value="${data.title}">
      <div>body:</div>
      <textarea>${data.body}</textarea>
    `
  },
  render() {
    this.$el.html(this.template(this.model.attributes))
    return this
  }
})
```

PostModelの`change`イベントに応じて、`attributes`プロパティをDOMに変換します。
変換したDOMは自信が管理するDOM(`$el`プロパティ)に追加します。

### PostCollection
```js
PostCollection = Backbone.Collection.extend({
  url: 'http://localhost:3000/posts',
  model: PostModel
})
```

RESTful APIのURLと、取得したレコードの変換先モデルを指定します。      

### AppView
```js
posts = new PostCollection(),
AppView = Backbone.View.extend({
  initialize() {
    this.listenTo(posts, 'add', this.render)
    posts.fetch()
  },
  render(post) {
    $('body').append(
      new PostView({
        model: post
      })
      .render()
      .$el
    )
  }
})
```

PostCollectionのインスタンスの`add`イベントに応じてビューを描画します。
PostViewを使って、PostModelをDOMに変換し、`body`タグに追加します。

# 関連記事
- [Backbone.jsでHello World （Backbone.Viewのサンプル）](http://qiita.com/ledsun/items/dde4f415205c888f54b4)
- [Backbone.jsのModel.fetch で RESTful API から情報取得](http://qiita.com/ledsun/items/d1146682e409c0687a1a)
- [Backbone.jsでModelに対応するViewをつくる](http://qiita.com/ledsun/items/dac6e7595ea9f28d30d2)
- [Bakcbone.jsとBrowserifyを一緒に使う](http://qiita.com/ledsun/items/e6703e703d4b3e7df7d7)