Backbone js集合收集问题

Kra*_*aoz 7 collections backbone.js

当我尝试使用骨干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,
})
Run Code Online (Sandbox Code Playgroud)

创建播放列表集合:

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()))
Run Code Online (Sandbox Code Playgroud)

这是输出:

{"name":"classic","tracks":[{"title":"fur elise"},{"title":"fuya"}]}
{"name":"c2c","tracks":[{"title":"fur elise"},{"title":"fuya"}]}
Run Code Online (Sandbox Code Playgroud)

问题是,正如我们在输出中看到的那样,2个播放列表有2个音轨"fur elise"和"fuya".

所以我的问题是为什么?为了在第一个名为"classic"和"fuya"的播放列表中仅在第二个名为"c2c"的播放列表中播放"fur elise",我该怎么做?

谢谢.

mu *_*ort 7

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

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

Backbone将defaults在创建新实例时进行浅层复制:

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

其结果是,每一个PlayList使用默认实例tracks将使用完全相同的TrackCollectiontracks属性,并且TrackCollection将成为一个被引用defaults.

最简单的解决方案是使用以下函数defaults:

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

这样,defaults当需要默认值时,将调用该函数,并且每次defaults调用时,您将TrackCollection在默认tracks属性中获得全新的内容.

以下是您的快速经验法则:

如果要将除字符串,数字或布尔值以外的任何内容放入其中defaults,请使用defaults函数而不是defaults对象.