7

バックボーン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つのプレイリストに「furelise」と「fuya」の2つのトラックがあることです。

だから私の質問はなぜですか?そして、「クラシック」という名前の最初のプレイリストにのみ「エリーゼのために」を、「c2c」という名前の2番目のプレイリストにのみ「フヤ」を含めるにはどうすればよいですか?

ありがとうございました。

4

1 に答える 1

7

私はあなたの問題があなたのデフォルトのtracks属性だと思いますPlayList

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

バックボーンは、defaults新しいインスタンスを作成するときにを浅くコピーします。

デフォルト model.defaults or model.defaults()
[...]
JavaScriptでは、オブジェクトは参照によって渡されるため、デフォルト値としてオブジェクトを含めると、すべてのインスタンス間で共有されることに注意してください。

その結果PlayList、デフォルトを使用するすべてのインスタンスは、その属性とtracksまったく同じものを使用し、それがで参照されるものになります。TrackCollectiontracksTrackCollectiondefaults

最も簡単な解決策は、次の関数を使用することですdefaults

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

そうdefaultsすれば、デフォルトが必要なときに関数が呼び出され、呼び出されるたびに、デフォルト属性でdefaultsまったく新しいものが取得されます。TrackCollectiontracks

これがあなたのための簡単な経験則です:

文字列、数値、ブール値以外のものをに入れたい場合は、オブジェクトの代わりに関数をdefaults使用してください。defaultsdefaults

于 2012-12-03T00:37:41.173 に答える