2012-12-03 18 views
8

私はバックボーンjsを使用してコレクションのコレクションを作成しようとするとisssueを実行しています。ここ はコードです:バックボーンjsコレクションのコレクション

モデルとコレクション:プレイリストコレクションの

var Track = Backbone.Model.extend({ 

    defaults : { 
     title : "" 
    } 
}) 

var TrackCollection = Backbone.Collection.extend({ 

    model : Track, 
}) 

var Playlist = Backbone.Model.extend({ 

    defaults : { 
     name : "", 
     tracks : new TrackCollection, 
    } 
}) 

var PlaylistCollection = Backbone.Collection.extend({ 

    model : Playlist, 
}) 

作成:

var playlists = new PlaylistCollection; 

// create and push the first playlist 
playlists.push({ name : "classic" }); 
// create and push a track in the playlist just created 
playlists.last().get("tracks").push({ title : "fur elise" }); 

// create and push the second playlist 
playlists.push({ name : "c2c" }); 
// create and push a track in the playlist just created 
playlists.last().get("tracks").push({ title : "fuya" }); 

// display first playlist 
console.log(JSON.stringify(playlists.at(0).toJSON())) 
// display second playlist 
console.log(JSON.stringify(playlists.at(1).toJSON())) 

ここでは、出力されます。

{"name":"classic","tracks":[{"title":"fur elise"},{"title":"fuya"}]} 
{"name":"c2c","tracks":[{"title":"fur elise"},{"title":"fuya"}]} 

問題があり、出力で見ることができるように、2つのプレイリストには2つのトラック「毛皮エリーゼ」と「fuy a "。

私の質問はなぜですか? 2番目のプレイリスト「c2c」の「classic」と「fuya」という最初のプレイリストにのみ「毛皮のエリート」を持たせるにはどうすればよいですか?

ありがとうございます。新しいインスタンスを作成するときに

var Playlist = Backbone.Model.extend({ 
    defaults : { 
     name : "", 
     tracks : new TrackCollection, 
    } 
}); 

バックボーンがdefaultsを浅いコピーされます:

答えて

8

私はあなたの問題はPlayListにあなたのデフォルトtracks属性だと思う

デフォルトmodel.defaults or model.defaults()
[.. 。]
JavaScriptでは、object sは参照渡しであるため、オブジェクトをデフォルト値として含めると、すべてのインスタンスで共有されます。

結果は、デフォルトtracksを使用するすべての単一のインスタンスがPlayListdefaultsで参照される1つになります正確にそのtracks属性と同じTrackCollectionとそのTrackCollectionを使用することです。

最も簡単な解決策は、defaultsのための機能を使用することです:

var Playlist = Backbone.Model.extend({ 
    defaults : function() { 
     return { 
      name : "", 
      tracks : new TrackCollection, 
     }; 
    } 
}); 

defaults機能がデフォルト値が必要なときに呼び出され、毎回defaultsは、あなたが新しいブランドTrackCollectionを得ることができますと呼ばれるその方法既定値はtracksです。ここで

は、親指の迅速なルールは、あなたのためです:

あなたの代わりにdefaultsオブジェクトのdefaults機能を使用し、defaults内の文字列、数値、またはブール値以外のものを入れたい場合。

+0

私はそれがインスタンス化時にデフォルトのコピーを実行していると思っていました。とにかく、お返事いただきありがとうございます! – Kraoz

+0

これは素晴らしい情報であり、非常に関係しますが、初期化メソッドで新しいコレクションを作成する方が簡単で簡単ですか? –

+1

@AlexMills:多分。私は彼らの状況について十分に知りませんでした。この答えは、「あなたがこれをやろうとすれば、それをこのやり方で行う」ことのようなものです。 –