Skip to content

Instantly share code, notes, and snippets.

@rafaelrinaldi
Last active August 29, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rafaelrinaldi/10897067 to your computer and use it in GitHub Desktop.
Save rafaelrinaldi/10897067 to your computer and use it in GitHub Desktop.
define([
'signals',
'hogan',
'mout/lang/isString',
'mout/object/forOwn'
], function(
Signal,
Hogan,
isString,
forOwn
) {
var p = Data.prototype;
/**
* Data is used to store parameters and even plain objects.
* @author Rafael Rinaldi (rafaelrinaldi.com)
* @date 2013-07-29
* @param {Object} data Optional initial data do be parsed.
* @param {Boolean} shouldEnableDataPersistence Whether data persistency should be enabled or not.
*/
function Data( data, shouldEnableDataPersistence ) {
// Internal linked list.
this.list = !!shouldEnableDataPersistence ? window.localStorage : {};
// Default key values.
this.defaults = {};
// Key spies.
this.spy = {};
}
/**
* Add a new data entry.
* @param {String} key Data key.
* @param {*} value Data value.
* @return {*} The value just added.
*/
p.set = function( key, value ) {
this.list[key] = JSON.stringify(value);
if(!!this.spy[key]) this.spy[key].dispatch(value);
return value;
};
/**
* Get data value.
* @param {String} key Data key.
* @return {*} Data value.
*/
p.get = function( key ) {
var value;
try {
value = JSON.parse(this.list[key]) || this.defaults[key];
} catch( error ) {
console.warn('[Data] :: get() :: Error when trying to retrieve the value of "%s"', key);
}
return isString(value) ? this._resolveString(value) : value;
};
/**
* Remove data value.
* @param {String} key Data key.
* @return {Data} Data instance.
*/
p.remove = function( key ) {
this.list[key] = null;
if(!!this.spy[key]) {
this.spy[key].dispose();
this.spy[key] = null;
}
delete this.list[key];
};
// Remove current items from list.
p.clear = function() {
if(this.shouldEnableDataPersistence) {
this.list.clear();
} else {
forOwn(this.list, function( value, key ) {
this.remove(key);
}, this);
}
};
/**
* Watches for a change on a specific key and fires a callback when it happens.
* @param {String} key Property key.
* @param {Function} callback Callback function.
*/
p.watch = function( key, callback ) {
if(!this.spy[key]) this.spy[key] = new Signal();
this.spy[key].add(callback);
};
/**
* Unwatches changes on a specific key. If no callback is given, it'll remove all callbacks provided for that very key.
* @param {String} key Property key.
* @param {Function} callback Callback function.
*/
p.unwatch = function( key, callback ) {
if(!this.spy[key]) {
console.warn('No active spy for "%s"', key);
return;
}
if(!!callback) {
this.spy[key].remove(callback);
} else {
this.spy[key].removeAll();
}
};
/**
* @param {String} key Data key.
* @return {Bolean} `true` if key exists, `false` otherwise.
*/
p.contains = function( key ) {
return !!this.list[key];
};
p.clone = function() {
return new Data(this.list);
};
/**
* Search for substitutions on string values. Uses Hogan to do the replacement.
* @param {String} value String to be replaced.
* @return {String} Parsed string.
*/
p._resolveString = function( value ) {
if(!value) return null;
var template = Hogan.compile(value);
return template.render(this.list);
};
// Remove from memory.
p.dispose = function() {
// Remove spies from memory.
forOwn(this.spy, function( value, key ) {
this.spy[key].dispose();
this.spy[key] = null;
delete this.spy[key];
}, this);
this.spy = null;
};
p.toString = function() {
return JSON.stringify(this.list);
};
return Data;
});
@rafaelrinaldi
Copy link
Author

watch/unwatch » AS1 says hi!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment