如何将Backbone集合中的模型克隆到另一个集合

时间:2013-03-01 17:56:12

标签: javascript jquery backbone.js underscore.js backbone-collections

我需要在一个骨干集合中克隆模型并添加然后将它们添加到另一个骨干集合中。 (以下新集合中的所有模型都必须是唯一的,并且与原始集合中的模型没有任何关联。)

这是我的代码:

collection1.each(function( model ) {
  var clone = new Backbone.Model( model.toJSON() );
  clone.set( this.idAttribute, null, { silent: true });
  collection2.add( clone );
});

这不太奏效。我只能将一个模型从collection1添加到collection2一次。如果我第二次尝试这样做,那就失败了。所以Backbone正在检测一个dup。

有关我做错的任何建议吗?

先谢谢你的帮助

2 个答案:

答案 0 :(得分:1)

在您提供的代码中,this.idAttribute可能不是您认为的那样,因此在没有ID的情况下不会创建模型,导致第二次复制模型时发生冲突。

Underscore是Backbone的硬依赖,因此您可以在集合的JSON表示上使用_.omit来过滤掉ID。例如,

function copyCollection(collection1, collection2){
    var idAttribute = collection1.model.prototype.idAttribute;

    var data = _.map(
        collection1.toJSON(), 
        function(obj){ return _.omit(obj, idAttribute); }
    );

    collection2.add(data);
}

var c1 = new Backbone.Collection([
    {id: 1, name: "N1"},
    {id: 2, name: "N2"}
]);
var c2 = new Backbone.Collection();

copyCollection(c1, c2);
copyCollection(c1, c2);
console.log(c2.toJSON());

小提琴http://jsfiddle.net/jT59v/

答案 1 :(得分:0)

这是一个老问题,但是@nikoshr和this答案帮助了我,所以我想加上我的贡献。

在我的情况下,我需要克隆包含嵌套集合的模型:

app.Collections.collection1 = Backbone.Collection.extend({
    model: app.Models.model1,
    clone: function() {
        return new this.constructor(_.map(this.models, function(model) { var clone = model.clone().unset('id', {silent: true}).unset('idAttribute', {silent: true}); return clone.set('collection2', clone.get('collection2').clone()); }));
    }
});

app.Collections.collection2 = Backbone.Collection.extend({
    model: app.Models.model2,
    clone: function() {
        return new this.constructor(_.map(this.models, function(model) { return model.clone().unset('id', {silent: true}).unset('idAttribute', {silent: true}); }));
    }
});

    var clone = this.model.clone().unset('id', {silent: true}).unset('idAttribute', {silent: true});
    clone.set('collection1', clone.get('collection1').clone());
    var copy = this.model.collection.add(clone, {parse: true});

所以在你的情况下,我猜你可以这样做:

app.Collections.collection1 = Backbone.Collection.extend({
    clone: function() {
        return new this.constructor(_.map(this.models, function(model) { return model.clone().unset('idAttribute', {silent: true}); }));
    }
});

collection2.add(collection1.clone().models);