first draft of basic validations

This commit is contained in:
Jeremy Ashkenas
2010-10-07 09:33:50 -04:00
parent d0e27756f2
commit ed1871cbfe
4 changed files with 43 additions and 11 deletions

2
TODO
View File

@@ -1,5 +1,3 @@
* Make Collection a Pseudo-array, a-la jQuery.
* Hook up data binding in the view. Both ways. Parallel to models.
* Add simple validations.

View File

@@ -35,10 +35,11 @@
// Backbone.Bindable
// -----------------
// A module that can be mixed in to any object in order to provide it with
// A module that can be mixed in to *any object* in order to provide it with
// custom events. You may `bind` or `unbind` a callback function to an event;
// `trigger`-ing an event fires all callbacks in succession.
//
// var object = {};
// _.extend(object, Backbone.Bindable);
// object.bind('expand', function(){ alert('expanded'); });
// object.trigger('expand');
@@ -160,14 +161,26 @@
// Set a hash of model attributes on the object, firing `changed` unless you
// choose to silence it.
set : function(attrs, options) {
// Extract attributes and options.
options || (options = {});
if (!attrs) return this;
attrs = attrs._attributes || attrs;
var now = this._attributes;
if ('id' in attrs) {
this.id = attrs.id;
if (this.collection) this.resource = this.collection.resource + '/' + this.id;
// Run validation if `validate` is defined.
if (this.validate) {
var error = this.validate(attrs);
if (error) {
this.trigger('error', error);
return false;
}
}
// Check for changes of `id`.
if ('id' in attrs) this.id = attrs.id;
// Update attributes.
for (var attr in attrs) {
var val = attrs[attr];
if (val === '') val = null;
@@ -179,6 +192,8 @@
}
}
}
// Fire the `change` event, if the model has been changed.
if (!options.silent && this._changed) this.change();
return this;
},
@@ -244,10 +259,10 @@
save : function(attrs, options) {
attrs || (attrs = {});
options || (options = {});
this.set(attrs, options);
if (!this.set(attrs, options)) return false;
var model = this;
var success = function(resp) {
model.set(resp.model);
if (!model.set(resp.model)) return false;
if (options.success) options.success(model, resp);
};
var method = this.isNew() ? 'POST' : 'PUT';
@@ -420,7 +435,7 @@
if (!(model instanceof Backbone.Model)) model = new this.model(model);
model.collection = this;
var success = function(model, resp) {
model.set(resp.model);
if (!model.set(resp.model)) return false;
model.collection.add(model);
if (options.success) options.success(model, resp);
};

View File

@@ -35,7 +35,7 @@
ul.toc_section {
font-size: 11px;
line-height: 14px;
margin: 5px 0 20px 0;
margin: 5px 0 15px 0;
padding-left: 0px;
list-style-type: none;
font-family: Lucida Grande;

View File

@@ -119,4 +119,23 @@ $(document).ready(function() {
ok(_.isEqual(lastRequest[1], doc));
});
});
test("model: validate", function() {
var lastError;
var model = new Backbone.Model();
model.validate = function(attrs) {
if (attrs.admin) return "Can't change admin status.";
};
model.bind('error', function(error) {
lastError = error;
});
var result = model.set({a: 100});
equals(result, model);
equals(model.get('a'), 100);
equals(lastError, undefined);
result = model.set({a: 200, admin: true});
equals(result, false);
equals(model.get('a'), 100);
equals(lastError, "Can't change admin status.");
});
});