Backbone js 集合问题 [英] Backbone js collection of collections issue

查看:14
本文介绍了Backbone js 集合问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用主干 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 中,对象是通过引用传递的,因此如果您包含一个对象作为默认值,它将在所有实例之间共享.

结果是每个使用默认 tracksPlayList 实例将使用与其 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 a defaults function instead of a defaults object.

这篇关于Backbone js 集合问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆