当我尝试使用骨干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个曲目“fur elise”和“fuya”。
所以我的问题是为什么?如果仅在名为“c2c”的第二个播放列表中的第一个名为“classic”和“fuya”的播放列表中有“fur elise”,我该怎么办?
谢谢。
答案 0 :(得分:7)
我认为您的问题是tracks
中的默认PlayList
属性:
var Playlist = Backbone.Model.extend({
defaults : {
name : "",
tracks : new TrackCollection,
}
});
Backbone会在创建新实例时对defaults
进行浅层复制:
默认
model.defaults or model.defaults()
[...]
请记住,在JavaScript中,对象是通过引用传递的,因此如果您将对象包含为默认值,它将在所有实例之间共享。
结果是,使用默认PlayList
的每个tracks
实例将使用与其TrackCollection
属性完全相同的tracks
和TrackCollection
defaults
将是defaults
中引用的那个。
最简单的解决方案是使用var Playlist = Backbone.Model.extend({
defaults : function() {
return {
name : "",
tracks : new TrackCollection,
};
}
});
的函数:
defaults
这样,当需要默认值时会调用defaults
函数,并且每次调用TrackCollection
时,您都会在默认的tracks
属性中获得全新的defaults
以下是您的快速经验法则:
如果您想在
defaults
中添加除字符串,数字或布尔值以外的任何内容,请使用defaults
函数而不是{{1}}对象。