5
votes

The Backbone documentation says:

Model.set will fail if validation fails - it won't set the value therefore it won't trigger any callback. We can pass { silent: true } to Model.set - then it will set the value but won't trigger any callback neither.

So,

Why does Backbone Model require a valid state to simply set an attribute value? What if we want to set attributes as the user interacts with the UI, but the model is not valid yet? It means change callbacks are unavailable unless we pass { silent: true } then manually trigger the change?!

Please say you know a better way of handling this :)

2

2 Answers

3
votes

I'm not sure how to answer the Why questions but you could say that there are arguments for why it is good that set runs validations. For instance, it makes it dead simple to do client side validation in real time.

If your problem could be solved by only validating the value that is currently being changed by the user, you can do that by combining your validate method with the hasChanged method.

For example something like this:

Backbone.Model.extend({
  defaults : { name : "" },

  validate : function (attrs) {
    var errors = {};
    if(this.hasChanged("name") && attr.name.length == 0) {
      errors.name = "Need a name yo!";
    }
    //...

    if(_.keys(errors).length > 0) {
      return errors;
    }
  }
})
3
votes

In Backbone whenever you call set on model , It keeps track of what attributes of model has been changed and what attributes are newly added.Calling validate allows it be more efficient in doing it .Passing {silent:true} as options in set function causes validate and change to not execute so if doesnt fire any change events.

If you want to set attributes as the user interacts with the UI, but the model is not valid yet

In this case you can set the change in a plain object make sure object keys are sames as model's attribute and then at some point just set in your model.

var uiChanges = {name:'x'}; //just fill it with your changes 
ur_model.set(uiModel); //then set it ,this way it fires change events only once

To check the diff between your plain object and model you can use the ur_model.changedAttributes(uiChanges);

changedAttributes - Return an object containing all the attributes that have changed, or false if there are no changed attributes.

You can further use it save only those attributes that have changed rather than saving entire model again.