sync.coffee | |
---|---|
Backbone.HookSyncThis file provides a function, The basic idea:
The file also provides two functions to add a new sync method to your existing classes.
OptionsAll three methods expect an object containing 1-4 of the CRUD methods:
Optionally, a Optionally, a Each of the CRUD method keys can have any of the following values:
If an object is used it can have the following attributes:
If you're using expandArguments, addOptions: false is implied. | CRUD = ['create', 'read', 'update', 'delete']
HANDLER_DEFAULTS =
addOptions: true |
Returns a copy of the class with sync extended by the handlers. | wrap = (cls, handlers) ->
nCls = cls
nCls:: = _.clone cls::
bind nCls, handlers
nCls |
Mutates an existing class to replace sync with a new sync method powered by the handlers. Preserves a reference to the existing sync, so any method not handled will fall through to the original. | bind = (cls, handlers) -> |
make knows to look at handlers.sync if the sync method is not bound in the handlers (or is bound as 'default'). If there is no cls::sync (the default case for Backbone), make will use Backbone.sync. | if cls::sync
handlers.sync ?= cls::sync
cls::sync = make handlers
cls |
Build a sync function compatable with Backbone out of one or more CRUD functions. Anything you don't override will get passed through to the default sync function. | make = (handlers) -> |
Handlers is a map of CRUD methods to the functions which should handle them + some other options. | |
Replace all of the string handler pointers with the actual handlers they point to. Replace 'default' with null | resolveHandlers handlers |
Normalize the handler to always be an object with a make method. | handlersToObjects handlers |
| applyDefaults handlers |
This is the sync-replacement we'll be returning | (method, model, options) ->
handler = handlers[method]
if handler
request = buildRequest handler, method, model, options
makeRequest handler, request, options
else |
This method is most likely gonna be overriding the model's sync method, so calling @sync would recurse, so we let the fall-through sync be passed in as an option.
| (handlers.sync or Backbone.sync) method, model, options |
In this context, a request is the object which will be passed
into the Unless you set handler.addOptions to false, the options object will be automatically merged with the attributes your return. The build function defaults to | buildRequest = (handler, method, model, options) ->
builder = handler.build ? model.toJSON
req = builder method, model, options
if handler.addOptions and not handler.expandArguments
req = _.extend {}, options, req
req
|
Do it! handler.returnsPromise gives you a convenient way to convert a method which normally returns a promise to work with Backbone's success and error handlers. It will replace the passed-in success and error handlers with noops so they are not called twice. | makeRequest = (handler, request, options) ->
if handler.returnsPromise
oldOptions = _.pick options, 'success', 'error'
options.success = options.error = ->
if handler.expandArguments
resp = handler.do request...
else
resp = handler.do request
if handler.returnsPromise
resp.done (data) ->
oldOptions.success data
resp.fail (err) ->
oldOptions.error err |
Handler can be passed in as either functions, or objects which have some more options and functions. To make it easier, lets make them objects all of the time. It modifies the passed in object in-place. | handlersToObjects = (handlers) ->
for type, handler of handlers when type in CRUD
if _.isFunction handler
handlers[type] =
do: handler |
Use handlers.defaults as the defaults for all of the other handlers. Modifies the passed-in object in-place. | applyDefaults = (handlers) ->
for type, handler of handlers when type in CRUD
handlers[type] = _.extend {}, HANDLER_DEFAULTS, handlers.defaults, handler |
Handlers can be string references to the keys of other handlers, or 'default'. Modifies the passed in object in-place. | resolveHandlers = (handlers) ->
for type, handler of handlers when type in CRUD
switch handler
when 'default' |
In this context, For convenience, normalize default to be falsy as we also support simply skipping the handler type to signify 'default' | handlers[type] = null
when 'create', 'update', 'read', 'delete' |
You can alias the handler to another handler. The most common usage of this is to map create to the same thing as update, e.g.:
This is only going to reliably work to one level of depth, you can't reference references. | handlers[type] = handlers[handler]
exports = {make, wrap, bind}
Backbone?.HookSync = exports
|