Skip to content

Instantly share code, notes, and snippets.

@davemo
Last active December 15, 2015 11:59
Show Gist options
  • Save davemo/5257159 to your computer and use it in GitHub Desktop.
Save davemo/5257159 to your computer and use it in GitHub Desktop.
Ever wanted to debounce only the AJAX portion of a Backbone.Model.save call, but still have the client-side attributes update immediately? This mixin uses composition and _.compose to give you that ability :D
app.mixins.addDebounceToModelSave = (model, milliseconds) ->
debouncedSaver = _.debounce(model.save, milliseconds)
setter = (attrs, options) ->
{attributes: model.set(attrs).attributes, options}
saver = (args) ->
debouncedSaver.call(model, args.attributes, args.options)
model.save = _.compose(saver, setter)
# some view that increments a quantity by 1 every time a user clicks
# we dont want to trigger an AJAX call on fast successive clicks...
app.views.QuantityView = Backbone.View.extend
events:
"click .increment" : "incrementByOne"
initialize: ->
# but we want our model.attributes to update instantly
# so our view can keep the DOM fragment representing quantity in sync
@model.on("change:quantity", @updateQuantityDisplay)
# so we mix in the behaviour
app.mixins.addDebounceToModelSave(@model, 750)
# now incrementByOne can be called multiple times in succession...
incrementByOne: =>
# our attributes update immediately, and we only have 1 AJAX call to the server
# but we only have to call model.save instead of model.set + model.save
@model.save({quantity: @model.get('quantity') + 1})
updateQuantity: (__, quantity) =>
@$(".quantity").text(quantity)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment