2012-12-03 169 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"}]} 

问题是,正如我们在输出中可以看到的那样,这两个播放列表中有两个曲目“fur elise”和“fuy”一个”。

所以我的问题是为什么?我应该怎么做才能在名为“c2c”的第二个播放列表中仅在名为“classic”和“fuya”的第一个播放列表中具有“fur elise”?

谢谢。

回答

8

我觉得你的问题是你的默认tracks属性在PlayList:创建新实例时

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

骨干将浅拷贝defaults

默认model.defaults or model.defaults()
[.. 。]
请记住,在JavaScript中,对象s是通过引用传递的,所以如果你包含一个对象作为默认值,它将在所有实例之间共享。

结果是使用默认tracks每一个PlayList例如将使用完全相同的TrackCollectiontracks属性和TrackCollection将是一个在defaults引用。

最简单的解决方法是使用一个功能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:也许吧。我对他们的情况不够了解。这个答案更像是“如果你要这样做,那就这样做”。 –