Permalink
Browse files

Add pull method to models for bulk ajax fetches

`.pull` is like `.fetch` with three differences:
  * it uses jquery's getJSON (bypassing the internal spine query queue)
  * it can pull one or multiple ids from a server
  * it has straightforward success/failure callback parameters

Why all this?
Firstly, I like to pull in records quickly when needed, so I think
the internal queue is unecessary for quick gets.  Think: youtube
frontend (unlimited data with selective gets) instead of a tiny
contact DB or calendar where pagination or fully loading the
dataset makes sense.

Secondly, I'd like to pull in one or multiple items at a time.  If I
set the pull id to 1,4,5,6,7 the server can parse the special id
and return multiple results from one request.  Alternatively, a
list of multiple IDs can be passed in and they will be grabbed
individually.

Thirdly, simple callbacks make me happy.  Attaching handlers to an
extra options parameter feels like using YUI in 2006.
  • Loading branch information...
mattsta committed Jun 8, 2012
1 parent 9e479cc commit 6e3fde667418d9abe10c849dd5dfd6ae26aba28f
Showing with 103 additions and 1 deletion.
  1. +59 −0 lib/ajax.js
  2. +8 −0 lib/spine.js
  3. +30 −1 src/ajax.coffee
  4. +6 −0 src/spine.coffee

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -83,8 +83,33 @@ class Collection extends Base
@all(params).success (records) =>
@model.refresh(records, options)

pull: (ids, successCallback = null, failureCallback = null) ->
ids = [ids] unless $.isArray(ids)
xhrPromises = []
xhrPromises.push(@xhrPull id) for id in ids
$.when.apply(this, xhrPromises).then(successCallback, failureCallback)


# Private

xhrPull: (id) ->
record = new @model(id: id)
d = $.Deferred (dfd) =>
jsonPromise = $.getJSON(Ajax.getURL(record))
jsonPromise.done (jsonObj) =>
newObj = null
if $.isArray jsonObj
newObj = []
@model.refresh obj for obj in jsonObj
newObj.push(@model.find obj.id) for obj in jsonObj
else
@model.refresh jsonObj
newObj = @model.find jsonObj.id
dfd.resolve newObj
jsonPromise.fail =>
dfd.reject id
d.promise()

recordsResponse: (data, status, xhr) =>
@model.trigger('ajaxSuccess', null, status, xhr)

@@ -183,6 +208,7 @@ Extend =
Model.Ajax =
extended: ->
@fetch @ajaxFetch
@pull @ajaxPull
@change @ajaxChange

@extend Extend
@@ -193,6 +219,9 @@ Model.Ajax =
ajaxFetch: ->
@ajax().fetch(arguments...)

ajaxPull: ->
@ajax().pull(arguments...)

ajaxChange: (record, type, options = {}) ->
return if options.ajax is false
record.ajax()[type](options.ajax, options)
@@ -205,4 +234,4 @@ Model.Ajax.Methods =
# Globals
Ajax.defaults = Base::defaults
Spine.Ajax = Ajax
module?.exports = Ajax
module?.exports = Ajax
@@ -196,6 +196,12 @@ class Model extends Module
else
@trigger('fetch', callbackOrParams)

@pull: (idOrCallback, successCallback, failureCallback) ->
if typeof idOrCallback is 'function'
@bind('pull', idOrCallback)
else
@trigger('pull', idOrCallback, successCallback, failureCallback)

@toJSON: ->
@recordsValues()

0 comments on commit 6e3fde6

Please sign in to comment.