Permalink
Browse files

fix model.schema

mvc Collection now takes optional index for add()
mvc.Collection.newModel()
mvc.sync.Ajax first implementation
mvc.sync.Local first implementation
  • Loading branch information...
1 parent cb17d0b commit 52036b8bc4f65ea4d5047bd235326a87b3af21e5 @rhysbrettbowen committed Feb 21, 2012
Showing with 167 additions and 44 deletions.
  1. +7 −1 README.md
  2. +16 −6 collection.js
  3. +29 −12 model.js
  4. +72 −14 sync/ajax.js
  5. +33 −2 sync/local.js
  6. +7 −7 sync/sync.js
  7. +1 −0 testApp/testApp.html
  8. +2 −2 testApp/testApp.js
View
@@ -64,4 +64,10 @@ mvc.Router uses goog.History and hash tokens to hold and manage the state of the
### changelog ###
-v0.1 - initial documentation and versioning
+v0.2 - fix model.Schema
+ - mvc.Collection now takes optional index for add()
+ - mvc.Collection.newModel adds a new model to the collection
+ - mvc.sync.Ajax first implementation
+ - mvc.sync.Local first implementation
+
+v0.1 - initial documentation and versioning
View
@@ -1,4 +1,4 @@
-// v0.1
+// v0.2
goog.provide('mvc.Collection');
goog.require('mvc.Model');
@@ -10,8 +10,9 @@ goog.require('goog.events.EventTarget');
* @constructor
* @extends mvc.Model
* @param {?Array.<mvc.Model>} models
+ * @param {mvc.Model} modelType is the base type of model to use when creating a new model in the collection
*/
-mvc.Collection = function(models) {
+mvc.Collection = function(models, modelType) {
goog.base(this);
/**
* @private
@@ -24,6 +25,8 @@ mvc.Collection = function(models) {
*/
this.comparator_ = null;
+ this.modelType_ = modelType;
+
goog.array.forEach(models || [], function(model) {
this.add(model, true);
}, this);
@@ -76,17 +79,18 @@ mvc.Collection.prototype.sort = function(silent) {
/**
* @param {mvc.Model|Array.<mvc.Model>} model
+ * @param {number=} ind
* @param {boolean=} silent
*/
-mvc.Collection.prototype.add = function(model, silent) {
+mvc.Collection.prototype.add = function(model, ind, silent) {
if(goog.isArray(model)) {
- goog.array.forEach(model, function(mod) {
- this.add(mod, silent);
+ goog.array.forEach(model.reverse(), function(mod) {
+ this.add(mod, ind, silent);
}, this);
return;
}
if(!goog.array.contains(this.models_, model)) {
- this.models_.push(model);
+ goog.array.insertAt(this.models_, model, (ind || this.models_.length));
goog.events.listen(model, goog.events.EventType.CHANGE, this.sort,
false, this);
this.sort(true);
@@ -95,6 +99,12 @@ mvc.Collection.prototype.add = function(model, silent) {
}
};
+mvc.Collection.prototype.newModel = function(ind, silent) {
+ var model = new this.modelType();
+ this.add(model, ind, silent);
+ return model;
+};
+
/**
* @param {mvc.Model|Array.<mvc.Model>} model
* @param {boolean=} silent
View
@@ -1,6 +1,6 @@
-// v0.1
+// v0.2
goog.provide('mvc.Model');
-goog.provide('mvc.Model.Schema');
+goog.provide('mvc.model.Schema');
goog.require('goog.array');
@@ -37,6 +37,9 @@ mvc.Model = function(attr, schema) {
* @type {?mvc.Model.Schema}
*/
this.schema_ = schema;
+
+ this.cid_ = goog.getUid();
+
goog.object.forEach(attr, function(val, name) {
this.attr_[name] = val;
}, this);
@@ -62,6 +65,13 @@ mvc.Model.prototype.get = function(key) {
}
/**
+ * @return {boolean}
+ */
+mvc.Model.prototype.isNew = function() {
+ return !!this.get('id');
+}
+
+/**
* @param {mvc.Model.Schema}
*/
mvc.Model.prototype.setSchema = function(schema) {
@@ -185,7 +195,11 @@ mvc.Model.prototype.fetch = function(callback, silent) {
* pushes the object to the sync
*/
mvc.Model.prototype.save = function() {
-
+ if(this.sync_)
+ if(this.isNew())
+ this.sync_.create(this);
+ else
+ this.sync_.update(this);
};
// binds a change event
@@ -222,32 +236,35 @@ mvc.Model.prototype.bind = function(name, el, fn) {
*
* @constructor
*/
-mvc.Model.Schema = function() {
+mvc.model.Schema = function(rules) {
/**
* @private
* @type {Object.<string, function(*):boolean>}
*/
this.schema_ = {};
+
+ if(rules)
+ this.set(rules);
};
/**
* @typdef {string|function(*, mvc.Model):boolean}
*/
-mvc.Model.Schema.Rule;
+mvc.model.Schema.Rule;
/**
* set rule(s) in the schema
*
* @param {string | Object.<string, mvc.Model.Schema.Rule>} key
* @param {mvc.Model.Schema.Rule=} val
*/
-mvc.Model.Schema.prototype.set = function(key, val) {
+mvc.model.Schema.prototype.set = function(key, val) {
if(goog.isString(key)) {
var temp = {};
temp[key] = val;
key = temp;
}
- goog.object.forEach(key, function(val, key) {
+ goog.object.extend(this.schema_, goog.object.map(key, function(val, key) {
if(goog.isString(val)) {
if(val.toLowerCase() == 'number') {
val = function(val, mod){return goog.isNumber(val);};
@@ -258,14 +275,14 @@ mvc.Model.Schema.prototype.set = function(key, val) {
}
}
if(val.exec) {
- val = function(value, mod) {return !!val.exec(value);};
+ val = goog.bind(function(regex, value, mod) {return !!regex.exec(value);}, this, val);
}
- }, this);
- goog.object.extend(this.schema_, key);
+ return val;
+ }, this));
};
-mvc.Model.Schema.prototype.validate = function(key, val) {
+mvc.model.Schema.prototype.validate = function(key, val) {
if(key in this.schema_)
- return this.schema_(key, val);
+ return this.schema_[key](val);
return true;
};
View
@@ -1,55 +1,113 @@
-// v0.1
+// v0.2
goog.provide('mvc.sync.Ajax');
goog.require('mvc.sync');
-goog.require('goog.net.XhrIo');
+goog.require('goog.net.XhrManager');
/**
* @implements {mvc.sync}
*/
-mvc.sync.Ajax = function() {
- this.baseUrl = "/"
+mvc.sync.Ajax = function(url) {
+
+ this.baseUrls_ = {};
+
+ if(goog.isString(url) || goog.isFunction(url)) {
+ url = {
+ create: url,
+ read: url,
+ update: url,
+ del: url,
+ };
+ }
+ goog.object.extend(this.baseUrls_, goog.object.map(url, function(val) {
+ if(goog.isString(val))
+ return function(model) {val.replace(/:(\w+)/g, function(id) {
+ return model.get(id);
+ });};
+ return val;
+ });
+ this.xhr_ = new goog.net.XhrManager();
+ this.sendCount_ = 0;
};
/**
* @inheritDoc
*/
mvc.sync.Ajax.prototype.create = function(model, callback) {
- goog.net.XhrIo.send(this.baseUrl, goog.bind(this.onComplete), this),
- "CREATE", undefined, model.getJson());
+ this.xhr_.send(this.sendCount_++, this.baseUrls_.create(model),
+ "POST", model.getJson(), undefined,
+ goog.bind(this.onCreateComplete, this, model, callback));
};
/**
* @inheritDoc
*/
mvc.sync.Ajax.prototype.read = function(model, callback) {
- goog.net.XhrIo.send(this.baseUrl, goog.bind(this.onComplete), this),
- "GET");
+ this.xhr_.send(this.sendCount_++, this.baseUrls_.read(model),
+ "GET", undefined, undefined,
+ goog.bind(this.onComplete, this, model, callback));
};
/**
* @inheritDoc
*/
mvc.sync.Ajax.prototype.update = function(model, callback) {
- goog.net.XhrIo.send(this.baseUrl, goog.bind(this.onComplete), this),
- "PUT", model.getJson());
+ this.xhr_.send(this.sendCount_++, this.baseUrls_.update(model),
+ "PUT", model.getJson(), undefined,
+ goog.bind(this.onUpdateComplete, this, model, callback));
};
/**
* @inheritDoc
*/
mvc.sync.Ajax.prototype.delete = function(model, callback) {
- goog.net.XhrIo.send(this.baseUrl, goog.bind(this.onComplete), this),
- "DELETE");
+ this.xhr_.send(this.sendCount_++, this.baseUrls_.del(model),
+ "DELETE", undefined, undefined,
+ goog.bind(this.onDeleteComplete, this, model, callback));
+};
+
+/**
+ * override this to do processing on returned data
+ *
+ * @param {mvc.Model} model
+ * @param {Function} callback
+ * @param {Event} e
+ */
+mvc.sync.Ajax.prototype.onCreateComplete_ = function(model, callback, e) {
+ var xhr = e.target;
+ model.set('id') = xhr.getResponseJson()['result']['id'];
+};
+
+/**
+ * override this to do processing on returned data
+ *
+ * @param {mvc.Model} model
+ * @param {Function} callback
+ * @param {Event} e
+ */
+mvc.sync.Ajax.prototype.onReadComplete_ = function(model, callback, e) {
+ var xhr = e.target;
+ var json = xhr.getResponseJson()['result'];
+ goog.model.set(json);
+};
+
+/**
+ * override this to do processing on returned data
+ *
+ * @param {mvc.Model} model
+ * @param {Function} callback
+ * @param {Event} e
+ */
+mvc.sync.Ajax.prototype.onUpdateComplete_ = function(model, callback, e) {
};
/**
* override this to do processing on returned data
*
+ * @param {mvc.Model} model
* @param {Function} callback
* @param {Event} e
*/
-mvc.sync.Ajax.prototype.onComplete_ = function(callback, e) {
-
+mvc.sync.Ajax.prototype.onDelComplete_ = function(model, callback, e) {
};
View
@@ -1,4 +1,35 @@
-// v0.1
-goog.provide('mvc.sync.local');
+// v0.2
+goog.provide('mvc.sync.Local');
+goog.require('goog.storage.Storage');
+goog.require('goog.storage.mechanism.HTML5LocalStorage');
+/**
+ * @implements {mvc.sync}
+ */
+mvc.sync.Local = function() {
+ this.store_ = new goog.storage.Storage(goog.storage.mechanism.HTML5LocalStorage);
+};
+
+mvc.sync.Local.prototype.getUID = function() {
+ this.counter_ = this.counter_||0;
+ return (this.counter_++)+"|"+parseInt((new Date()).getTime(), 36);
+};
+
+mvc.sync.Local.prototype.create = function(model, callback) {
+ var id = this.getUID();
+ model.set('id') = id;
+ this.store_.update(model);
+};
+
+mvc.sync.Local.prototype.read = function(model, callback) {
+ model.set(this.store_.get(model.get('id')));
+};
+
+mvc.sync.Local.prototype.update = function(model, callback) {
+ this.store_.set(model.get('id'), model.toJson());
+};
+
+mvc.sync.Local.prototype.delete = function(model, callback) {
+ this.store_.remove(model.get('id'));
+};
Oops, something went wrong.

0 comments on commit 52036b8

Please sign in to comment.