Created
November 19, 2012 14:52
-
-
Save drphrozen/4111076 to your computer and use it in GitHub Desktop.
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
angular.module('LocalCacheModule', []). | |
factory('LocalCache', ['$q', '$log', function(q, log) { | |
var retrievers = {}; | |
var ttls = {}; | |
var localCache = { | |
retrieve: function(key, ready) { | |
var retriever = retrievers[key]; | |
if (angular.isFunction(retriever)) { | |
retriever(function(data) { | |
localCache.put(key, data); | |
ready(data); | |
}); | |
} else { | |
log.error("A function was not registered for the given cache key!"); | |
} | |
}, | |
get: function(key, readyCallback, forceUpdate) { | |
var item = { value: null }; | |
if (!angular.isFunction(readyCallback)) { | |
readyCallback = angular.noop; | |
} | |
var tryGetItem = function() { | |
var tmp = localStorage.getItem(key); | |
if (tmp !== null) { | |
item = angular.fromJson(tmp); | |
} | |
return tmp !== null; | |
}; | |
if (retrievers[key]) { | |
if (forceUpdate === true || !localCache.isAlive(key) || !tryGetItem()) { | |
// Force update or TTL expired | |
localCache.retrieve(key, function (data) { | |
angular.copy(data || {}, item); | |
readyCallback(data); | |
}); | |
} else { | |
readyCallback(item); | |
} | |
return item; | |
} else { | |
item = localStorage.getItem(key); | |
return item === null ? null : angular.fromJson(item); | |
} | |
}, | |
register: function(key, retrieve, ttl) { | |
if (!angular.isFunction(retrieve) || angular.isUndefined(ttl)) { | |
log.error('register must be called with a retrieve function and a valid ttl'); | |
return; | |
} | |
localCache.registerRetriever(key, retrieve); | |
localCache.registerTtl(key, ttl); | |
}, | |
registerTtl: function(key, ttl) { | |
ttls[key] = { ttl: ttl }; | |
localCache.updateTimeout(key); | |
}, | |
updateTimeout: function(key, tryUpdate) { | |
var ttlObj = ttls[key]; | |
if (angular.isUndefined(ttlObj) && tryUpdate !== true) { | |
log.error('registerTtl was not called for ' + key); | |
return; | |
} | |
var ttl = ttlObj.ttl; | |
var timeout; | |
if (angular.isNumber(ttl)) { | |
timeout = new Date(ttl + +new Date); | |
} else if (angular.isString(ttl)) { | |
switch (ttl) { | |
case 'midnight': | |
var d = new Date; | |
d.setHours(0, 0, 0, 0); | |
timeout = d; | |
break; | |
default: | |
log.error('ttl is not a valid value: ' + ttl); | |
return; | |
} | |
} else { | |
log.error('ttl is not a valid value: ' + ttl); | |
return; | |
} | |
ttlObj.timeout = timeout; | |
}, | |
isAlive: function(key) { | |
var ttlObj = ttls[key]; | |
return angular.isUndefined(ttlObj) || ttlObj.timeout > +new Date; | |
}, | |
registerRetriever: function(key, retrieve) { | |
retrievers[key] = retrieve; | |
}, | |
unregister: function(key) { | |
delete retrievers[key]; | |
delete ttls[key]; | |
}, | |
put: function(key, value) { | |
localStorage.setItem(key, angular.toJson(value)); | |
localCache.updateTimeout(key, true); | |
}, | |
remove: function(key) { | |
localStorage.removeItem(key); | |
} | |
}; | |
return localCache; | |
}]). | |
factory('Cacheable', ['LocalCache', '$log', function (localCache, log) { | |
var CacheableFactory = function (key) { | |
if (!angular.isString(key)) { | |
log.error("key must be of type string!"); | |
return undefined; | |
} | |
var obj = {}; | |
angular.forEach(['get', 'put', 'remove', 'register', 'registerTtl', 'registerRetriever', 'updateTimeout', 'isAlive', 'unregister'], function (value) { | |
obj[value] = function () { | |
var args = Array.prototype.slice.call(arguments); | |
args.splice(0, 0, key); | |
localCache[value].apply(localCache[value], args); | |
}; | |
}); | |
return obj; | |
}; | |
return CacheableFactory; | |
}]); |
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
angular.module('MyApp', ['LocalCacheModule', 'ngResource']); | |
var MyController = function ($scope, Cacheable, $resource) { | |
var bar = Cacheable('bar'); | |
// register() overrides previous registrations for this key | |
bar.register(function (callback) { | |
var response = resource('/foo/bar').get({}, function() { | |
callback(response); | |
}) | |
}, 5000); | |
var baz = Cacheable('baz'); | |
baz.register(function (callback) { | |
callback(+new Date); | |
}, 'midnight'); | |
// Simple get, supports all datatypes | |
scope.Bar = undefined; | |
bar.get(function (data) { | |
scope.Bar = data; | |
}); | |
// Shorthand, ala $resource.get, only supports object types | |
scope.Baz = baz.get(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment