mvbl fst
mvbl fst

Reputation: 5263

Backbone JS: how to disable sync for delete?

I am dealing with a threaded comments collection, and when I delete a comment that has children, I do model.destroy() for this comment, and on the server side all its branches get deleted.

I wrote a function that once a node is deleted from the tree, looks for all orphans and removes them too. So when I find orphans, I run model.destroy() on them too but because they're already deleted on the server, sync returns errors.

Is there a way to disable sync for some destroy() calls?

Upvotes: 21

Views: 10112

Answers (5)

Jesse Suero
Jesse Suero

Reputation: 21

This allows you to respect the destroy call, including any success handlers

Backbone.Model.extend({
    destroy: function (options) {
       // don't make a server call, just delete from collection and call success
       this.trigger('destroy', this, this.collection, options);
       if (options && options.success) {
              options.success();
       }
    }
});

Upvotes: 2

Sam
Sam

Reputation: 6160

Building on fcarriedo's answer, just override the destroy method in your Model's declaration:

Models.YourModelName = Backbone.Model.extend({
    destroy: function () {
        this.id = null;
        Backbone.Model.prototype.destroy.apply(this, arguments);
    }
});

Upvotes: 1

Chris Dutrow
Chris Dutrow

Reputation: 50372

Ran into this same problem.

Using the model's link to its containing collection to remove the model from that collection was my preferred solution since this was exactly what I wanted to do and very clear in the code:

// From the view
this.model.collection.remove(this.model);

Upvotes: 1

fcarriedo
fcarriedo

Reputation: 176

This is kind of late but might work as an alternate solution for other people having the same problem.

Confronted with a very similar problem, I ended up setting all the children IDs to null before calling destroy on them. This way, backbone thinks that they are new and doesn't spawn a DELETE HTTP request to the server upon removal.

deleteParent: function() {
  this.model.children.each(function(child) {
    // Set to null so that it doesn't try to spawn a 'DELETE' http request 
    // on 'destroy' since thinks its new (hack).
    child.id = null; 
    child.destroy();
  });
  // This one DOES result in a 'DELETE' http request since it has an ID.
  this.model.destroy();
},

Upvotes: 2

Edward M Smith
Edward M Smith

Reputation: 10627

Since all the destroy method does is send a DELETE request and triggers destroy, simply triggering destroy is exactly what you're looking for.

model.trigger('destroy', model, model.collection, options);

Yeah, it feels a bit hackish, but that's pretty much all the Backbone code does anyway. If you want, and if you have a base model you extend from, you could add this as a method on that base model, and it might not feel quite so hackish.

Upvotes: 33

Related Questions