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 个播放列表有 2 个曲目“fur elise”和“fuya”。

所以我的问题是为什么?我应该怎么做才能让“fur elise”只出现在名为“classic”的第一个播放列表中,而“fuya”只出现在名为“c2c”的第二个播放列表中?

谢谢你。

4

1 回答 1

7

我认为您的问题是您的默认tracks属性PlayList

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

defaults创建新实例时,Backbone 将浅拷贝:

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,请使用defaults函数而不是defaults对象。

于 2012-12-03T00:37:41.173 回答