Reputation: 6664
I need to clone the models in one backbone collection and add then add them to another. (IOW all of the models in the new collection need to be unique, and have no connection to the models in the original collection.)
Here is my code:
collection1.each(function( model ) {
var clone = new Backbone.Model( model.toJSON() );
clone.set( this.idAttribute, null, { silent: true });
collection2.add( clone );
});
This doesn't quite work. I can only add a model from collection1 to collection2 once. If I try to do it a second time, it fails. So somehow Backbone is detecting a dup.
Any suggestions on what I am doing wrong?
Thanks (in advance) for your help
Upvotes: 3
Views: 3285
Reputation: 664
That's an old question, but @nikoshr and this answers helped me so I'd like to add my contribution.
In my case I needed to clone a model including nested collections :
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});
So in your case I guess you could do something like that :
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);
Upvotes: 0
Reputation: 33344
In the code you provided, this.idAttribute
is probably not what you think it is and thus won't create models without their ids, leading to collisions when you copy the models a second time.
Underscore is a hard dependency of Backbone, so you can use _.omit
on the JSON representation of your collection to filter out the ids. For example,
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());
And a Fiddle http://jsfiddle.net/jT59v/
Upvotes: 1