Backbone.sync = function(method, model, options) { // we need to make sure we initialize a store, in this case // we will just use a JS object. var cache = {}; // The size will be primarily used to assign ids to newly // created models. Each time a new model is created, the size // will be incremented. var size = 0; // since we need to create a store for the models/collections // we are actually going to invoke the outer function which will // return this function below as the Backbone.sync that will // actually be used. return function(method, model, options) { // create a new deferred object. standard sync returns the $.ajax // request, which internally returns a deferred. It's important to // do this so that people can chain on fetch using the standard .then/.fail // syntax, rather than just the success/error callbacks. var deferred = $.Deferred(); // when creating a new model... if (method === "create") { // first assign it an id. The server would traditionally do this. model.id = size; // store it in our cache cache[model.id] = model; // make sure we increment the number of models we now have. size += 1; // if a success callback was provided, execute it. if (options.success) { options.success(model, model.toJSON(), options); } // resolve the deferred. deferred.resolve(model); // we are updating a model } else if (method === "update") { // as long as the model actually exists in our store if (cache[model.id]) { // overwrite what is currently in the store with this model. cache[model.id] = model; // if a success callback was provided, execute it. if (options.success) { options.success(model, model.toJSON(), options); } deferred.resolve(model); // if this model doesn't exist yet, we can't update it } else { if (options.error) { options.error(model, "Model not found"); } deferred.reject(model); } // if we're trying to read a model... } else if (method === "read") { // as long as it exists if (cache[model.id]) { // if a success callback was provided, execute it. if (options.success) { options.success(model, cache[model.id].toJSON(), options); } // resolve deferred.resolve(model); } else { if (options.error) { options.error(model, "Model not found"); } deferred.reject(model); } // if we're deleting a model... } else if (method === "delete") { // first make sure it exists in the cache if (cache[model.id]) { // then remove it from the cache delete cache[model.id]; // and trigger the success callback. Note we're passing an // empty object as the second argument, because a deletion // would result in an empty return from the server. if (options.success) { options.success(model, {}, options); } // resolve the deferred deferred.resolve(model); // otherwise, error that the model doesn't exist. } else { if (options.error) { options.error(model, "Model not found"); } deferred.reject(model); } } return deferred.promise(); } }();