Created
February 7, 2012 05:12
-
-
Save mikeknoop/1757353 to your computer and use it in GitHub Desktop.
Backbone Simple Cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### | |
Lightweight Backbone Cache | |
Mike Knoop, 2012 (knoopgroup.com, zapier.com) | |
Simply execute this script file sometime after you load Backbone. | |
It hooks into the Backbone sync function to give a lightweight local | |
cache for models and collections. Will work for both models and collections. | |
Only GET requests are eligible for cacheing and caches are stored by URL. | |
Example "usage" | |
MyModel.fetch() # will GET from server on first call, from cache then on | |
MyModel.fetch({cache: false}) # force GET from server | |
MyModel.fetch({expiry: 5000}) # GET from server if cache is expiry milliseconds old | |
### | |
# initialize cache store | |
window.BackboneCache = {} | |
# namespace cache methods | |
Backbone.cache = () -> | |
# save sync for later use | |
Backbone._sync = Backbone.sync | |
# map sync methods | |
methodMap = | |
'create': 'POST' | |
'update': 'PUT' | |
'delete': 'DELETE' | |
'read': 'GET' | |
# convienence method to access properties as either props or urls | |
getValue = (object, prop) -> | |
return null if not object? or not object[prop]? | |
return object[prop]() if _.isFunction(object[prop]) | |
return object[prop] | |
# returns boolean if a cache exists/non-expired for a url | |
Backbone.cache.exists = (url) -> | |
if window.BackboneCache?[url]? | |
return true | |
else | |
return false | |
# set some json into the cache | |
Backbone.cache.set = (url, json, status, xhr) -> | |
time = new Date().getTime() | |
window.BackboneCache[url] = {} | |
window.BackboneCache[url].url = url | |
window.BackboneCache[url].time = time | |
window.BackboneCache[url].json = json | |
window.BackboneCache[url].status = status | |
window.BackboneCache[url].xhr = xhr | |
# retrieve som json from the cache | |
Backbone.cache.get = (url) -> | |
return window.BackboneCache?[url] | |
# clear a specific cache | |
Backbone.cache.clear = (url) -> | |
if window.BackboneCache[url]? | |
delete window.BackboneCache[url] | |
# clear a specific cache if expired (expiry milliseconds have elapsed) | |
Backbone.cache.expire = (url, expiry) -> | |
if Backbone.cache.exists(url) | |
now = new Date().getTime() | |
cache = Backbone.cache.get(url) | |
if (cache.time + expiry) < now | |
Backbone.cache.clear(url) | |
# define cached sync method to hook in | |
Backbone.sync = (method, model, options) -> | |
type = methodMap[method] | |
url = getValue(model, 'url') | |
# cache only GET request responses | |
# and make sure we have a url | |
if type == 'GET' and url? | |
# if `cache: false` passed the cache for the url is cleared | |
# forcing a refresh from the server | |
if options.cache? and not options.cache | |
Backbone.cache.clear(url) | |
# if `expiry: int` passed, compare lifespan of cache and clear | |
# it if lifespan > expiry | |
if options.expiry? | |
Backbone.cache.expire(url, options.expiry) | |
# short-circuit fetch and return cache if it exists | |
if Backbone.cache.exists(url) | |
cache = Backbone.cache.get(url) | |
options.success(cache.json, cache.status, cache.xhr) | |
return | |
# callback to set cache from successful response | |
success = options.success | |
options.success = (resp, status, xhr) => | |
Backbone.cache.set(url, resp, status, xhr) | |
success(resp, status, xhr) | |
# sync to actual server | |
Backbone._sync(method, model, options) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var getValue, methodMap; | |
Backbone._sync = Backbone.sync; | |
window.BackboneCache = {}; | |
Backbone.cache = function() {}; | |
methodMap = { | |
'create': 'POST', | |
'update': 'PUT', | |
'delete': 'DELETE', | |
'read': 'GET' | |
}; | |
getValue = function(object, prop) { | |
if (!(object != null) || !(object[prop] != null)) return null; | |
if (_.isFunction(object[prop])) return object[prop](); | |
return object[prop]; | |
}; | |
Backbone.cache.exists = function(url) { | |
var _ref; | |
if (((_ref = window.BackboneCache) != null ? _ref[url] : void 0) != null) { | |
return true; | |
} else { | |
return false; | |
} | |
}; | |
Backbone.cache.set = function(url, json, status, xhr) { | |
var time; | |
time = new Date().getTime(); | |
window.BackboneCache[url] = {}; | |
window.BackboneCache[url].url = url; | |
window.BackboneCache[url].time = time; | |
window.BackboneCache[url].json = json; | |
window.BackboneCache[url].status = status; | |
return window.BackboneCache[url].xhr = xhr; | |
}; | |
Backbone.cache.get = function(url) { | |
var _ref; | |
return (_ref = window.BackboneCache) != null ? _ref[url] : void 0; | |
}; | |
Backbone.cache.clear = function(url) { | |
if (window.BackboneCache[url] != null) return delete window.BackboneCache[url]; | |
}; | |
Backbone.cache.expire = function(url, expiry) { | |
var cache, now; | |
if (Backbone.cache.exists(url)) { | |
now = new Date().getTime(); | |
cache = Backbone.cache.get(url); | |
if ((cache.time + expiry) < now) return Backbone.cache.clear(url); | |
} | |
}; | |
Backbone.sync = function(method, model, options) { | |
var cache, success, type, url, | |
_this = this; | |
type = methodMap[method]; | |
url = getValue(model, 'url'); | |
if (type === 'GET' && (url != null)) { | |
if ((options.cache != null) && !options.cache) Backbone.cache.clear(url); | |
if (options.expiry != null) Backbone.cache.expire(url, options.expiry); | |
if (Backbone.cache.exists(url)) { | |
cache = Backbone.cache.get(url); | |
options.success(cache.json, cache.status, cache.xhr); | |
return; | |
} | |
success = options.success; | |
options.success = function(resp, status, xhr) { | |
Backbone.cache.set(url, resp, status, xhr); | |
return success(resp, status, xhr); | |
}; | |
} | |
return Backbone._sync(method, model, options); | |
}; |
I should update the gist, Ive since updated the script to be a little more
robust.
…On Jul 18, 2012 9:46 AM, "jp pincheira" < ***@***.***> wrote:
Thanks! Works like a charm. :)
---
Reply to this email directly or view it on GitHub:
https://gist.github.com/1757353
Mike can you update this gist??
Thanks,
Hey Mike,
I would love to see your updated version!
Thanks!
Ditto, would love to see the updated version.
Thanks.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks! Works like a charm. :)