問題について
Collection に格納しようとしている Model の attributes、またはサーバからのレスポンスに、 オブジェクト構造をもつ id というプロパティ がありますか。
もしあるならば、十中八九それが原因とみて間違いないでしょう。
ここで重要なのは、オブジェクト構造を持つプロパティの名前が id であるということです。
{
id: {
shopId : 'hogeShop',
humanId: 'TaroYamada'
}
}
このような構造を持つオブジェクトを setメソッドや addメソッド で Collection に複数詰めようとしても、Collection には1つの Model しか格納されません。
var attrs = [
{ id: { shopId : 'hogeShop', humanId: 'TaroYamada' } },
{ id: { shopId : 'hogeShop', humanId: 'JiroTanaka' } }
];
new Backbone.Collection(attrs);
実行結果(GoogleChrome for Windows 40.0.2214.111 m)
配列の1番目だけが Model として格納されてしまいました。
調査しきれていない調査
Collection.set 周りのコードを調べてみたところ、Collection に Model を詰める過程で、詰めた履歴を変数に保持する際に Model.id を利用していました。
デフォルトの状態では、 Model.id は、Model.attributes.id を値に持ちます。
このとき、Model.id の値がオブジェクト構造になってしまっていると、Collection へ格納する際に期待した振る舞いをすることができなくなってしまうようです。
お恥ずかしながら、 Collection.set 周辺の挙動について詳細を読み解ききれませんでした。
この部分についてご存じの方がいらっしゃいましたら、コメントにてご教授頂ければ幸いです。
対処法
Model.id にオブジェクト構造でない値を指定してあげれば良いので、 Backboneオブジェクトごとに自動生成される cid を指定して問題を回避するのが良いみたいです。
Model.idAttribute に任意の文字列を渡すと、 Model.attributes のどの値を Model.id として持たせたいか指定することができます。
var attrs = [
{ id: { shopId : 'hogeShop', humanId: 'TaroYamada' } },
{ id: { shopId : 'hogeShop', humanId: 'JiroTanaka' } }
];
new Backbone.Collection(attrs, { model: Backbone.Model.extend({ idAttribute: 'cid' }) });
実行結果(中身の確認のため、変数に取り出しています)
今度はうまくできました。やったね。
実際のコードではこのような書き方になるのかな、と思います。
var Collection = Backbone.collection.extend({
model: Backbone.Model.extend({ idAttribute: 'cid' });
});
var collection = new Collection(attrs);
突っ込みどころ、誤った認識をしている箇所がありましたら是非ご指摘ください。

