Backbone js 集合问题 [英] Backbone js collection of collections issue
问题描述
当我尝试使用主干 js 创建集合集合时遇到了一个问题.这是代码:
I'm running into an isssue when I try to create a collection of collections using backbone js. Here is the code :
模型和集合:
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".
The problem is, as we can see on the output, the 2 playlists have the 2 tracks "fur elise" and "fuya".
所以我的问题是为什么?为了让fur elise"只出现在名为classic"的第一个播放列表中,而fuya"只出现在名为c2c"的第二个播放列表中,我该怎么做?
So my question is why ? and what should I do in order to have "fur elise" only in the first playlist named "classic" and "fuya" only in the second playlist named "c2c" ?
谢谢.
推荐答案
我认为您的问题是您在 PlayList
中的默认 tracks
属性:
I think your problem is your default tracks
attribute in PlayList
:
var Playlist = Backbone.Model.extend({
defaults : {
name : "",
tracks : new TrackCollection,
}
});
Backbone 将在创建新实例时浅复制defaults
:
Backbone will shallow-copy the defaults
when creating new instances:
defaults model.defaults 或 model.defaults()
[...]
请记住,在 JavaScript 中,对象是通过引用传递的,因此如果您包含一个对象作为默认值,它将在所有实例之间共享.
结果是每个使用默认 tracks
的 PlayList
实例将使用与其 tracks 完全相同的
TrackCollection
属性,并且 TrackCollection
将是 defaults
中引用的那个.
The result is that every single PlayList
instance that uses the default tracks
will be using exactly the same TrackCollection
as its tracks
attribute and that TrackCollection
will be the one referenced in the defaults
.
最简单的解决方案是使用 defaults
函数:
The easiest solution is to use a function for defaults
:
var Playlist = Backbone.Model.extend({
defaults : function() {
return {
name : "",
tracks : new TrackCollection,
};
}
});
这样 defaults
函数将在需要默认值时被调用,每次 defaults
被调用时,你都会得到一个全新的 TrackCollection
在默认的 tracks
属性中.
That way the defaults
function will be called when defaults are needed and each time defaults
is called you'll get a brand new TrackCollection
in the default tracks
attribute.
这里有一个简单的经验法则供您参考:
Here's a quick rule of thumb for you:
如果您想在 defaults
中放入字符串、数字或布尔值以外的任何内容,请使用 defaults
函数而不是 defaults
对象.
If you want to put anything other than strings, numbers, or booleans in
defaults
, use adefaults
function instead of adefaults
object.
这篇关于Backbone js 集合问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!