Created
July 10, 2014 18:30
-
-
Save rafaelrinaldi/5cee2fc24266024b235c 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. | |
*/ | |
function Data( data ) { | |
// Internal linked list. | |
this.list = {}; | |
// Default key values. | |
this.defaults = {}; | |
// Key spies. | |
this.spy = {}; | |
// Merge predefined data if it does exist. | |
if(!!data) this.merge(data); | |
} | |
/** | |
* Merge existing data. | |
* @param {Object} data Data model. | |
*/ | |
p.merge = function( data ) { | |
forOwn(data, function( value, key ) { | |
this.set(key, value); | |
}, this); | |
}; | |
/** | |
* 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