Permalink
Browse files

fixes so it compiles in closure-compiler

change to using more options objects
ajaxsync uses goog.uri.querydata
schema throws errors when no match
schema can change the data to be saved
  • Loading branch information...
1 parent c2d7197 commit 3dfbe5656c170f6fdecf6c833ca357f03f9b1283 @rhysbrettbowen committed Mar 14, 2012
Showing with 99 additions and 40 deletions.
  1. +2 −0 README.md
  2. +33 −9 collection.js
  3. +55 −25 model.js
  4. +4 −2 sync/ajax.js
  5. +5 −4 sync/sync.js
View
@@ -118,6 +118,8 @@ you can then register your object with the mediator and the messages that you ma
#### v0.7 ###
- add in mvc.Mediator
+- schema now throws errors and handles them
+- fixes
#### v0.6 ####
View
@@ -11,18 +11,29 @@ goog.require('mvc.Model');
goog.require('goog.events.Event');
goog.require('goog.events.EventTarget');
+
/**
* A collection of models
*
* @constructor
* @extends mvc.Model
- * @param {?Array.<mvc.Model>} models
- * @param {function(new:mvc.Model)=} modelType is the base type of model to use when creating a new model in the collection
- * @param {mvc.Sync=} sync
+ * @param {Object=} options
*/
-mvc.Collection = function(models, modelType, sync) {
- goog.base(this);
- this.sync_ = sync;
+mvc.Collection = function(options) {
+ goog.base(this, options);
+
+ var defaults = {
+ sync: null,
+ comparator: null,
+ modelType: mvc.Model,
+ models: [],
+ schema: null
+ };
+
+ if(options)
+ goog.object.extend(defaults, options);
+
+ this.sync_ = defaults.sync;
/**
* @private
* @type {Array.<mvc.Model>}
@@ -32,19 +43,20 @@ mvc.Collection = function(models, modelType, sync) {
* @private
* @type {?function(mvc.Model, mvc.Model):number}
*/
- this.comparator_ = null;
+ this.comparator_ = defaults.comparator;
/**
* @private
*/
- this.modelType_ = modelType;
+ this.modelType_ = defaults.modelType;
- goog.array.forEach(models || [], function(model) {
+ goog.array.forEach(defaults.models, function(model) {
this.add(model, undefined, true);
}, this);
};
goog.inherits(mvc.Collection, mvc.Model);
+
/**
* @return {Array}
*/
@@ -183,6 +195,18 @@ mvc.Collection.prototype.getById = function(id) {
}
/**
+ * get all the models, optionally filter by function
+ *
+ * @param {function(mvc.Model):Boolean=} filter
+ * @return {Array.<mvc.Model>}
+ */
+mvc.Collection.prototype.getModels = function(filter) {
+ if(filter)
+ return goog.array.filter(this.models_, /** @type {Function} */(filter));
+ return this.models_.slice(0);
+};
+
+/**
* get a model by it's index in the collection
*
* @param {number} index
View
@@ -22,15 +22,23 @@ goog.require('goog.object');
* @param {Object=} options can take in the arguments attr, schema and sync
*/
mvc.Model = function(options) {
- options = options || {};
+ var defaults = {
+ schema: null,
+ sync: null,
+ attr: []
+ };
+
+ if(options)
+ goog.object.extend(defaults, options);
+
/**
* @private
* @type {Object.<string, ?Object>}
*/
this.attr_ = {};
/**
* @private
- * @type {Object.<string, ?Function>}
+ * @type {Object.<{attr: Array.<string>, fn: Function}>}
*/
this.formats_ = {};
/**
@@ -42,9 +50,9 @@ mvc.Model = function(options) {
* @private
* @type {?mvc.model.Schema}
*/
- this.schema_ = options.schema || null;
+ this.schema_ = defaults.schema || null;
- this.sync_ = options.sync|| null;
+ this.sync_ = defaults.sync|| null;
this.cid_ = goog.getUid(this);
@@ -54,13 +62,14 @@ mvc.Model = function(options) {
this.dispatchEvent(goog.events.EventType.LOAD);
};
-
goog.inherits(mvc.Model, goog.events.EventTarget);
+
+
/**
* returns full copy of the attributes
*
- * @return {Object.<string, Object>}
+ * @return {!Object}
*/
mvc.Model.prototype.toJson = function() {
return goog.object.clone(this.attr_);
@@ -108,9 +117,10 @@ mvc.Model.prototype.has = function(key) {
* @param {Object|string} key object of key value pairs to set, or the key
* @param {Object=} val to use if the key is a string
* @param {boolean=} silent true if no change event should be fired
- * @return {mvc.Model}
+ * @return {boolean}
*/
mvc.Model.prototype.set = function(key, val, silent) {
+ var success = true;
if(goog.isString(key)) {
var temp = {};
temp[key] = val;
@@ -120,14 +130,23 @@ mvc.Model.prototype.set = function(key, val, silent) {
this.prev_ = goog.object.clone(this.attr_);
}
goog.object.forEach(key, function(val, key) {
- if(!this.schema_ || this.schema_.validate(key, val)) {
+ if(!this.schema_ || val == undefined) {
this.attr_[key] = val;
+ } else {
+ var validate = this.schema_.validate(key, val);
+ if(goog.isDef(validate))
+ this.attr_[key] = validate;
+ else
+ success = false;
}
}, this);
- if(!silent) {
- this.dispatchEvent(goog.events.EventType.CHANGE);
+ if(success) {
+ if(!silent) {
+ this.dispatchEvent(goog.events.EventType.CHANGE);
+ }
+ return true;
}
- return this;
+ return false;
};
/**
@@ -148,8 +167,8 @@ mvc.Model.prototype.alias = function(newName, oldName) {
* Can be used to change format returned when using get, e.g:
* model.format('date', function(date) {return date.toDateString();});
*
- * @param {string} newName
- * @param {string} oldName
+ * @param {string} attr
+ * @param {Function} fn
*/
mvc.Model.prototype.format = function(attr, fn) {
this.formats_[attr] = {attr: [attr],
@@ -182,7 +201,7 @@ mvc.Model.prototype.meta = function(attr, require, fn) {
/**
* @param {string} key
* @param {boolean=} silent true if no change event should be fired
- * @return {mvc.Model}
+ * @return {boolean}
*/
mvc.Model.prototype.unset = function(key, silent) {
return this.set(key, undefined, silent);
@@ -209,15 +228,16 @@ mvc.Model.prototype.prev = function(key) {
* returns object of changed attributes and their values
*/
mvc.Model.prototype.getChanges = function() {
- return
- goog.object.filter(this.formats_, function(val) {
+ var ret = goog.object.getKeys(goog.object.filter(this.formats_, function(val) {
return goog.array.some(val.attr, function(require) {
return this.attr_[require] != this.prev_[require];
}, this);
- }, this);
- goog.object.filter(this.attr_, function(val, key) {
- return val != this.prev_[key];
- }, this);
+ }, this));
+ goog.array.extend(ret, goog.object.getKeys(goog.object.filter(this.attr_,
+ function(val, key) {
+ return val != this.prev_[key];
+ }, this)));
+ return ret;
};
/**
@@ -297,7 +317,7 @@ mvc.Model.prototype.getBinder = function(key) {
*
* @param {string|Array.<string>} name
* @param {Function|*} el
- * @param {Function|*} fn
+ * @param {Function|*=} fn
*/
mvc.Model.prototype.bind = function(name, el, fn) {
goog.events.listen(this, goog.events.EventType.CHANGE, function(e) {
@@ -383,10 +403,20 @@ mvc.model.Schema.Test = function(obj) {
}
return false;
};
-}
+};
+
+mvc.model.Schema.prototype.onErr = function(message) {
+ alert(message);
+};
mvc.model.Schema.prototype.validate = function(key, val) {
- if(key in this.schema_)
- return this.schema_[key](val);
- return true;
+ if(key in this.schema_) {
+ try{
+ return this.schema_[key](val);
+ } catch(err) {
+ this.onErr(err.message);
+ return undefined;
+ }
+ }
+ return val;
};
View
@@ -4,6 +4,7 @@ goog.provide('mvc.AjaxSync');
goog.require('mvc.Sync');
goog.require('goog.net.XhrManager');
+goog.require('goog.Uri.QueryData');
/**
* @constructor
@@ -44,8 +45,9 @@ mvc.AjaxSync = function(url) {
* @inheritDoc
*/
mvc.AjaxSync.prototype.create = function(model, callback) {
+
this.xhr_.send(""+(this.sendCount_++), this.baseUrls_.create(model),
- "POST", model.toJson().toString(), undefined, undefined,
+ "POST", goog.Uri.QueryData.createFromMap(model.toJson()).toString(), undefined, undefined,
goog.bind(this.onCreateComplete_, this, model, callback));
};
@@ -63,7 +65,7 @@ mvc.AjaxSync.prototype.read = function(model, callback) {
*/
mvc.AjaxSync.prototype.update = function(model, callback) {
this.xhr_.send(""+(this.sendCount_++), this.baseUrls_.update(model),
- "PUT", model.toJson().toString(), undefined, undefined,
+ "PUT", goog.Uri.QueryData.createFromMap(model.toJson()).toString(), undefined, undefined,
goog.bind(this.onUpdateComplete_, this, model, callback));
};
View
@@ -10,9 +10,10 @@ goog.provide('mvc.Sync');
*/
mvc.Sync = function() {};
-/**
- * @enum {number}
- */
+
+/*
+This can be used for HTTP status
+
mvc.Sync.Status = {
// Successful
OK: 200,
@@ -34,7 +35,7 @@ mvc.Sync.Status = {
NOT_IMPLEMENTED: 501,
BAD_GATEWAY: 502,
GATEWAY_TIMEOUT: 504
-}
+}*/
/**
* take in the model to push to server (use .toJson()) and call callback when done

0 comments on commit 3dfbe56

Please sign in to comment.