简体   繁体   中英

Globally listen for Backbone.js Model.save

I'd like to append Backbone's native Model.save() method with a custom logging method that logs success and errors. I know that on a per model basis I can call something like:

myModel.save().success(function() {
    // do something cool
});

But rather than adjusting every call to various models' save events, I'd like to simply listen for the save event on any model. One way that I think I want to avoid is actually modifying the Backbone.Model.prototype.save method (although if someone has an elegant way to do this I'm open to it).

Any thoughts on how to create such an event listener?

If all your models/collections are using the default Backbone.sync method, you could create a new sync method to do the logging.

   var originalSync = Backbone.sync;
   var loggingSync = function(method, model, options) {
         // call original Backbone.sync
         var promise = originalSync(method, model, options);
         promise.done(function() {
            // if method is 'update' or 'create', log success
         });
         promise.fail(function() {
            // if method is 'update' or 'create', log failure
         });
         return promise;
      };
   Backbone.sync = loggingSync;

By default, Model.sync and Collection.sync both proxy through to Backbone.sync, so if you are using default sync, this change would take care of it.

var GlobalModel = Backbone.Model.extend({
save: function() {

}
});

myModel = GlobalModel.extend({
//..your model
})

If all you want to do is log AJAX success/failures, there's actually a much better way of doing it that doesn't even involve Backbone at all: $.ajaxComplete .

jQuery has this wonderful function called ajaxComplete that takes a function argument, and then runs that function every time a $.ajax call completes (failure or success). By using this method (ie. "binding an event handler to the ajaxComplete pseudo-event") you:

A) don't have to muck with Backbone internals

B) are guaranteed to catch EVERY AJAX request (even those made without Backbone)

C) keep this logging code completely separate from the rest of your code

There's probably some other upsides I'm missing, but you get the idea.

If on the other hand you truly do care only about save and not just about AJAX requests, then ... well you could still use $.ajaxComplete and just do some filtering inside it to ignore non-saves. But you could also make your own Model base class (as @salexch suggested) or worse you could muck with Backbone's internals, eg. by replacing Backbone.Model.prototype.save or Backbone.sync (as @Paul Hoenecke suggested), but then you're setting yourself up for trouble with future Backbone upgrades or 3rd party Backbone libraries you might want to use.

If you're interested, here's the doc page for ajaxComplete : http://api.jquery.com/ajaxComplete/

Oh, and there's also some similarly named $.ajaxSomething methods (eg. ajaxError ) for targeting only failures/successes/request starts/etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM