Backbone.js入門 「View と Model と Collection の連携」 

### 閲覧上の注意

この記事で対象としているバージョン0.5.3は結構古いので注意してください。

その他の割りと新しい情報は [Backbone.js Advent Calendar 2012](http://www.adventar.org/calendars/15) などにあります。

（追記ここまで）

----

Backbone.js入門シリーズも佳境に差し掛かってきました。
`View` と `Model` の連携は既に取り上げたので、今回は特に `Collection` と `View` `Model` との連携に主眼を当てて記述したいと思います。

##View と Collection の連携

復習の意味も込めて、`View` と `Model` の連携方法をもう一度記述すると、大枠として次のようになります。

```js
// モデルの定義
Hoge = Backbone.Model.extend({});

// ビューの定義
HogeView = Backbone.View.extend({
    events: {
        "click .submit": "update" // DOM のイベントを監視
    },
    initialize: function (options) {
        _.bindAll(this, "render", "remove");
        // オブザーバパターンを利用してモデルのイベントを購読
        this.model.bind("change", this.render);
        this.model.bind("destroy", this.remove);
    },
    update: function () {
        this.model.set({foo: "bar"}); // change が発生し、this.render が呼ばれる
    },
    render: function () {
        $(this.el).html(_.template($("#hoge-template").html(), this.model.attributes));
        return this;
    },
    remove: function () {
        $(this.el).remove();
        return this;
    }
});

// モデルのインスタンス
hoge = new Hoge();

// モデルを渡してビューを初期化
hogeView = new HogeView({model: hoge});
```

`View` は `Model` へのリファレンスを保持していますが `Model` から見て `View` はイベントの購読者の一人に過ぎない という関係になっています。
`View` と `Collection` の関係も基本的に同じ構造となります。

```js
HogeList = Backbone.Collection.extend({
    model: Hoge
});

HogeListView = Backbone.View.extend({
    events: {
        "click .add": "addItem"
    },
    initialize: function (options) {
        _.bindAll(this, "resetItems", "appendItem", "removeItem");

        this.collection.bind("reset", this.resetItems);
        this.collection.bind("add", this.appendItem);
        this.collection.bind("remove", this.removeItem);
    },
    addItem: function () {
        var model = new Hoge();
        this.collection.add(model); // add イベントが発生し、this.appendItem が呼ばれる
    },
    resetItems: function (collection) {
        collection.each(function (model) {
            this.appendItem(model); 
        }, this);
    },
    appendItem: function (model) {
        var view = new HogeView({model: model});
        $(this.el).append(view.render().el);
    },
    removeItem: function (model) {
        model.destroy();
    }
});

hogeList = new HogeList();
hogeListView = new HogeListView({collection: hogeList});
```

##Model と Collection の連携

`Model` と `Collection` は互いのリファレンスを保持しています。`model.collection` と `collection.models` です。

```js
hoge = new Hoge();
hogeList = new HogeList();

hoge.collection // => undefined
hogeList.models // => []

hogeList.add(hoge);

hoge.collection === hogeList // => true
hogeList.models[0] === hoge // => true

hogeList.include(hoge) // => true

hogeList.remove(hoge);

hoge.collection // => undefined
hogeList.models // => []
```

##おわりに

ユーザの入力によって `View` のメソッドが呼ばれ、その中で `Collection` を操作し、その操作の結果生じるイベントによって `View` の見た目を更新する、という流れになります。これは、`View` と `Model` の連携と同じ流れです。

さて、いよいよ次回最終回は `Router` と `History` です。
それではまた明日。

---

1. [Backbone.js入門 Events](http://qiita.com/items/16b799d0ec0a0ae3f78e)
2. [Backbone.js入門 MVC](http://qiita.com/items/03f49c64d6c4bacdbb26)
3. [Backbone.js入門 View](http://qiita.com/items/8ee2ed1949cd7c337f06)
4. [Backbone.js入門 Model](http://qiita.com/items/5acef8dd49f67fd7813c)
5. [Backbone.js入門 ViewとModelの連携](http://qiita.com/items/7ce4b1ceb5d18c9cef08)
6. [Backbone.js入門 Collection](http://qiita.com/items/c19d2fff0dc23e4015ff)
7. Backbone.js入門 ViewとModelとCollectionの連携
8. [Backbone.js入門 RouterとHistory](http://qiita.com/items/13f3d1f71d31f3e78123)

- [BackboneJS 日本語メーリングリスト](https://groups.google.com/forum/?fromgroups#!forum/backbonejs-ja)