Last active
August 29, 2015 13:59
-
-
Save rafaelrinaldi/10897067 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
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; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
watch
/unwatch
» AS1 says hi!