Skip to content

Instantly share code, notes, and snippets.

@thomsbg
Last active December 22, 2015 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomsbg/6527302 to your computer and use it in GitHub Desktop.
Save thomsbg/6527302 to your computer and use it in GitHub Desktop.
Backbone ajax mixin
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