Permalink
Browse files

add in format function on mvc.Mdoel

  • Loading branch information...
1 parent 400bdb3 commit 1cd9ab030ee16c7381ad7be56f53fcd6fce0c57e @rhysbrettbowen committed Feb 28, 2012
Showing with 71 additions and 1 deletion.
  1. +6 −0 README.md
  2. +48 −1 model.js
  3. +17 −0 model_test.js
View
@@ -35,6 +35,8 @@ When creating a new model instance, the constructor takes two optional arguments
You should always use the get() and set() functions when dealing with the model's data. These functions take care of saving old data and publishing change events
+There is also a format function that allows you to format the data when you get it, or even create new attributes using existing ones
+
## mvc.model.Schema ##
A schema can be set for a model. The schema takes in an object or map of keys and functions. The functions take in a value and return true or false. When a schema is passed in to a model, the model will use this to validate any values trying to be set, and won't add in data if a function returns false. You can also pass in the following strings to check for the type of input: "number", "string", "array"
@@ -64,6 +66,10 @@ mvc.Router uses goog.History and hash tokens to hold and manage the state of the
### changelog ###
+#### v0.5 ####
+
+- add in format function on model
+
#### v0.4 ####
- added pluck in to mvc.Collection
View
@@ -35,6 +35,11 @@ mvc.Model = function(attr, schema, sync) {
this.attr_ = {};
/**
* @private
+ * @type {Object.<string, ?Function>}
+ */
+ this.formats_ = {};
+ /**
+ * @private
* @type {Object.<string, ?Object>}
*/
this.prev_ = {};
@@ -75,6 +80,8 @@ mvc.Model.prototype.setSync = function(sync) {
* @return {Object=}
*/
mvc.Model.prototype.get = function(key) {
+ if(this.formats_[key])
+ return this.formats_[key]();
return goog.object.get(this.attr_, key, null);
}
@@ -129,6 +136,44 @@ mvc.Model.prototype.set = function(key, val, silent) {
};
/**
+ * Can be used to change the output of an attribute, or create alias or
+ * meta-attributes.
+ * change get format like this:
+ * model.format('date', function(date) {
+ * return date.getMonth()+"/"+date.getYear();});
+ * setup a new alias
+ * model.format('last_name', 'surname');
+ * setup a meta-attr
+ * model.format('date', ['day', 'month', 'year'], function(day, month, year) {
+ * return day+"/"+month+"/"+year;});
+ *
+ * @param {string} attr the new attribute name or attribute to set a format for
+ * @param {Function|string|Array.<string>} formatter the formatting function,
+ * the attribute to alias or an array of attributes to use. The function will
+ * be passed the value and be bound to the model
+ * @param {Function=} fn function to put together the meta-attribute
+ * @return {mvc.Model}
+ */
+mvc.Model.prototype.format = function(attr, formatter, fn) {
+ if(goog.isString(formatter)) {
+ this.formats_[attr] = goog.bind(function() {
+ return this.attr_[formatter];
+ }, this);
+ } else if (goog.isFunction(formatter)) {
+ this.formats_[attr] = goog.bind(function() {
+ return formatter(this.attr_[attr], this);
+ }, this);
+ } else if (goog.isArrayLike(formatter)) {
+ this.formats_[attr] = goog.bind(function() {
+ return fn.apply(this, goog.array.map(formatter, function(val) {
+ return this.attr_[val];
+ }, this));
+ }, this);
+ }
+ return this;
+}
+
+/**
* @param {string} key
* @param {boolean=} silent true if no change event should be fired
* @return {mvc.Model}
@@ -236,13 +281,15 @@ mvc.Model.prototype.getBinder = function(key) {
* if no name is passed (null or undefined) then the operation will be run on
* any change to the model and pass in the model
*
- * @param {string} name
+ * @param {string|Array.<string>} name
* @param {Element|Node|Function|*} el
* @param {Function|*} fn
*/
mvc.Model.prototype.bind = function(name, el, fn) {
goog.events.listen(this, goog.events.EventType.CHANGE, function(e) {
var changes = e.target.getChanges();
+ if(goog.isString(name))
+ name = [name];
if(name in changes || !goog.isDefAndNotNull(name)) {
if(goog.isFunction(el)) {
goog.bind(el, fn)(changes[name], this);
View
@@ -22,3 +22,20 @@ var testSimpleModel = function() {
var testEmptyModel = function() {
assertNotNull(emptyModel);
};
+
+var testFormatter = function() {
+ simpleModel.set('date', {day:1,month:1});
+ simpleModel.format('1jan2010', 'date');
+ assertEquals(simpleModel.get('1jan2010'), simpleModel.get('date'));
+ simpleModel.format('date', function(date) {
+ return date.day+"/"+date.month;
+ });
+ assertEquals(simpleModel.get('date'), "1/1");
+ simpleModel.set('day',1);
+ simpleModel.set('month',1);
+ simpleModel.format('jan1', ['day', 'month'], function(day, month) {
+ return day+"/"+month;
+ });
+ assertEquals(simpleModel.get('jan1'),"1/1");
+
+};

0 comments on commit 1cd9ab0

Please sign in to comment.