The post How to shuffle a JavaScript array appeared first on Đào Thanh Tú (Front-end Developer).
]]>The array isn’t a primitive so Arrays are passed by reference. It means that array passed as a parameter will be changed when we will modify it inside the function:
// Initial array will be changed after shuffle function mutableShuffle(arr) { var j; var temp for (var i = 0, max = arr.length; i < max; i++) { j = Math.floor(Math.random() * max); temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } return arr; }
The function above doesn’t modify a given array. It creates, fills and returns a new array:
// Initial array will NOT be changed after shuffle function immutableShuffle(arr) { var result = []; var j; var temp; for (var i = 0, max = arr.length; i < max; i++) { j = Math.floor(Math.random() * max); temp = arr[i]; result[i] = arr[j]; result[j] = temp; } return result; }
var mutableArr = [1, 2, 3]; console.log(mutableShuffle(mutableArr)); console.log(mutableArr); // will be changed var immutableArr = [1, 2, 3]; console.log(immutableShuffle(immutableArr)); console.log(immutableArr); // will NOT be changed
You can try and modify it on codepen.
The post How to shuffle a JavaScript array appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post Codepen.io – Animated folding (notifications concept) appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post Codepen.io – Animated folding (notifications concept) appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post Codepen.io – Matrix animated filling using different approaches appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post Codepen.io – Matrix animated filling using different approaches appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post Codepen.io – Alarm clock concept appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post Codepen.io – Alarm clock concept appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post Codepen.io – Chat concept appeared first on Đào Thanh Tú (Front-end Developer).
]]>
The post Codepen.io – Chat concept appeared first on Đào Thanh Tú (Front-end Developer).
]]>The post How to cache Backbone.js collections and models in LocalStorage appeared first on Đào Thanh Tú (Front-end Developer).
]]>At first, write a simple wrapper for caching of JS-objects in the LocalStorage with the ability to specify the duration of the cache:
var StoreWithExpiration = function() { return { set: function(key, value, expireTime) { var item = { value: value, expireTime: expireTime, cachedAt: new Date().getTime() }; try { localStorage.setItem(key, JSON.stringify(item)); } catch(e) {} }, get: function(key) { try { var info = JSON.parse(localStorage.getItem(key)); if (!info || new Date().getTime() - info.cachedAt > info.expireTime) return null; return info.value; } catch(e) { localStorage.removeItem(key); } } }; };
Then extend Backbone.Collection by the method cachedFetch. A lifetime of the cache can be set by parameter expireTime (default lifetime equals 1 hour). The logic is simple:
var expirationStore = new StoreWithExpiration(); Backbone.Collection = Backbone.Collection.extend({ cachedFetch: function(options) { options = options || {}; var expireTime = options.expireTime || 60 * 60 * 1000; var cacheKey = 'bbCollection_' + this.url; if (!window.localStorage) return this.fetch(options); var cachedData = expirationStore.get(cacheKey); var cachedModels = cachedData ? cachedData.value : []; var success = options.success; if (!cachedData) { options.success = _.bind(function (resp) { if (success) success.call(options.context, this, resp, options); expirationStore.set(cacheKey, this.models, expireTime); }, this); return this.fetch(options); } else { options = _.extend({parse: true}, options); var method = options.reset ? 'reset' : 'set'; this[method](cachedModels, options); if (success) success.call(options.context, this, cachedModels, options); this.trigger('sync', this, cachedModels, options); return this.sync('cachedRead', this, options); } } });
And for the models:
Backbone.Model = Backbone.Model.extend({ cachedFetch: function(options) { options = options || {}; var expireTime = options.expireTime || 60 * 60 * 1000; var cacheKey = 'bbModel_' + this.url + '_' + this.id; if (!window.localStorage) return this.fetch(options); var cachedData = expirationStore.get(cacheKey); var cachedModel = cachedData ? cachedData.value : {}; var success = options.success; if (!cachedData) { options.success = _.bind(function (resp) { if (success) success.call(options.context, this, resp, options); expirationStore.set(cacheKey, this.models, expireTime); }, this); return this.fetch(options); } else { options = _.extend({parse: true}, options); var serverAttrs = options.parse ? model.parse(cachedModel, options) : cachedModel; if (!model.set(serverAttrs, options)) return false; if (success) success.call(options.context, this, cachedModel, options); this.trigger('sync', this, cachedModel, options); return this.sync('cachedRead', this, options); } } });
And finally, patch Backbone.Sync to support our caching:
var _sync = Backbone.sync; Backbone.sync = function(method, model, options) { if (method === 'cachedRead') { var _getCacheKey = function() { return model.collection ? 'bbModel_' + model.url + '_' + model.id : 'bbCollection_' + model.url; }; var _getCachedValue = function() { var cachedData = expirationStore.get(_getCacheKey()); var empty = model.collection ? {} : []; return cachedData ? cachedData.value : empty; }; if (options.success) options.success(_getCachedValue()); } else { return _sync.apply(this, arguments); } }
The full source code for this plugin you can find on github.
The post How to cache Backbone.js collections and models in LocalStorage appeared first on Đào Thanh Tú (Front-end Developer).
]]>