Skip to content

Commit

Permalink
error events are now always passed the model as the first argument. Y…
Browse files Browse the repository at this point in the history
…ou may now also pass an error callback to set() and save(), if the callback is passed, it will be called instead of the 'error' event getting fired.
  • Loading branch information
jashkenas committed Oct 19, 2010
1 parent b854b28 commit a09bcbc
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 9 deletions.
26 changes: 17 additions & 9 deletions backbone.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,16 @@
if (attrs.attributes) attrs = attrs.attributes;
var now = this.attributes;

// Run validation if `validate` is defined.
// Run validation if `validate` is defined. If a specific `error` callback
// has been passed, call that instead of firing the general `"error"` event.
if (this.validate) {
var error = this.validate(attrs);
if (error) {
this.trigger('error', this, error);
if (options.error) {
options.error(this, error);
} else {
this.trigger('error', this, error);
}
return false;
}
}
Expand Down Expand Up @@ -193,10 +198,11 @@
options || (options = {});
var model = this;
var success = function(resp) {
if (!model.set(resp.model)) return false;
if (!model.set(resp.model, options)) return false;
if (options.success) options.success(model, resp);
};
Backbone.sync('read', this, success, options.error);
var error = options.error && _.bind(options.error, null, model);
Backbone.sync('read', this, success, error);
return this;
},

Expand All @@ -209,11 +215,12 @@
if (!this.set(attrs, options)) return false;
var model = this;
var success = function(resp) {
if (!model.set(resp.model)) return false;
if (!model.set(resp.model, options)) return false;
if (options.success) options.success(model, resp);
};
var error = options.error && _.bind(options.error, null, model);
var method = this.isNew() ? 'create' : 'update';
Backbone.sync(method, this, success, options.error);
Backbone.sync(method, this, success, error);
return this;
},

Expand All @@ -226,7 +233,8 @@
if (model.collection) model.collection.remove(model);
if (options.success) options.success(model, resp);
};
Backbone.sync('delete', this, success, options.error);
var error = options.error && _.bind(options.error, null, model);
Backbone.sync('delete', this, success, error);
return this;
},

Expand Down Expand Up @@ -399,7 +407,8 @@
collection.refresh(resp.models);
if (options.success) options.success(collection, resp);
};
Backbone.sync('read', this, success, options.error);
var error = options.error && _.bind(options.error, null, collection);
Backbone.sync('read', this, success, error);
return this;
},

Expand All @@ -410,7 +419,6 @@
if (!(model instanceof Backbone.Model)) model = new this.model(model);
model.collection = this;
var success = function(resp) {
if (!model.set(resp.model)) return false;
model.collection.add(model);
if (options.success) options.success(model, resp);
};
Expand Down
24 changes: 24 additions & 0 deletions test/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,28 @@ $(document).ready(function() {
equals(lastError, "Can't change admin status.");
});

test("Model: validate with error callback", function() {
var lastError, boundError;
var model = new Backbone.Model();
model.validate = function(attrs) {
if (attrs.admin) return "Can't change admin status.";
};
var callback = function(model, error) {
lastError = error;
};
model.bind('error', function(model, error) {
boundError = true;
});
var result = model.set({a: 100}, {error: callback});
equals(result, model);
equals(model.get('a'), 100);
equals(lastError, undefined);
equals(boundError, undefined);
result = model.set({a: 200, admin: true}, {error: callback});
equals(result, false);
equals(model.get('a'), 100);
equals(lastError, "Can't change admin status.");
equals(boundError, undefined);
});

});

0 comments on commit a09bcbc

Please sign in to comment.