Last active
December 22, 2015 20:29
-
-
Save thomsbg/6527302 to your computer and use it in GitHub Desktop.
Backbone ajax mixin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
App.Mixins.Ajax = { | |
// Override urls in the target object to contain a map of | |
// actionName => /url/path/with/:bound/:segments | |
urls: {}, | |
// Any options specified here are merged with those you pass to | |
// this.ajax({...}) before being passed to jQuery.ajax | |
ajaxOptions: {}, | |
// Return the matching url from the 'urls' object, with /:path/:segments | |
// bound to attribute values of the same name. | |
// Return undefined if action is not a key of the 'urls' object. | |
urlFor: function(action) { | |
var url = this.urls[action]; | |
if (url) { | |
url = url.replace(/:([^\/]+)/, _.bind(function(match, capture) { | |
return (this instanceof Backbone.Model) ? this.get(capture) : this[capture]; | |
}, this)); | |
} | |
return url; | |
}, | |
// Simple wrapper for jQuery.ajax with some default options + events | |
// - The "url" option is determined by calling urlFor on the 1st arg. | |
// if urlFor returns nothing, than an error is raised. | |
// - Other options come from defaults, this.ajaxOptions, and the 2nd arg. | |
// - On success, the "#{action}Success" event is triggered, and the | |
// "ajaxSuccess" event is triggered on Chorus.Comments. | |
// - The "#{action}Error" and "ajaxError" events are triggered similarly. | |
// - The "success" and "error" options are called from within the default | |
// callbacks, before any events are triggered. | |
ajax: function(action, options) { | |
var url = this.urlFor(action); | |
if (!url) { | |
throw 'ArgumentError: No url specified for action: ' + action; | |
} | |
// Create settings from defaults, this.ajaxOptions, and passed options | |
var resource = this; | |
var settings = _.extend({ | |
url: url, | |
dataType: 'json', | |
context: resource // Execute callbacks in the context of the resource | |
}, this.ajaxOptions || {}, options); | |
// Specify a default error callback that triggers some events | |
settings.error = function(xhr, status, message) { | |
// If a error callback was passed as an option, call it first | |
if (options && _.isFunction(options.error)) { | |
options.error.call(settings.context, resource, message); | |
} | |
// Trigger error events on both the resource, and on the global App object | |
resource.trigger(action + 'Error', resource, message, xhr); | |
App.trigger('ajaxError', xhr, status, message, resource); | |
}; | |
// Specify a default success callback that triggers some events | |
settings.success = function(response, status, xhr) { | |
// If a success callback was passed as an option, call it first | |
if (options && _.isFunction(options.success)) { | |
options.success.call(settings.context, resource, response); | |
} | |
// Trigger success events on both the resource and on the global App object | |
resource.trigger(action + 'Success', resource, response, xhr); | |
App.trigger('ajaxSuccess', response, status, xhr, resource); | |
}; | |
// Trigger start events for things like loading indicators to listen to | |
resource.trigger(action + 'Start', resource); | |
App.trigger('ajaxStart', resource); | |
// Return the jqXHR object so more callbacks can be attached | |
return jQuery.ajax(settings); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment