Backbone.js: Reset a Model’s Attributes Locally

I recently ran into a situation with Backbone where I wanted to reset the attributes of a model to their original state (at the time of creation) without calling model.fetch().

window.ExampleModel = Backbone.Model.extend({
        defaults : {}

        initialize : function(){
                // Store the original attributes for resetting
                this._originalAttributes = _.clone(this.attributes);
        },

        /* Reset one or more attributes */
        reset : function(attrs, opts){
                opts || (options = {});

                var now = this.attributes,
                        escaped = this._escapedAttributes,
                        original = this._originalAttributes;

                // Test if we're reseting all attributes, or just one
                if( typeof attrs !== 'object' )
                        attrs = !attrs ? _.keys(now) : [attrs];

                // Reset the attributes.
                for( var i = 0; i < attrs.length; i++ ){
                        var attr = attrs[i];
                        var val = original[attr];

                        if ( !_.isEqual(now[attr], val) ){
                                now[attr] = val;
                                delete escaped[attr];
                                if (!options.silent)
                                        this.trigger('reset:' + attr, this, val, options);
                        }
                }

                if( !options.silent )
                        this.trigger('reset', this, attrs, options);
        }
});

window.exampleView = Backbone.View.extend({

        events: {'click .cancel' : 'cancel'}

        cancel : function(event){
                // Reset all attributes to their original state
                this.model.reset();

                // Reset one attribute
                //this.mode.reset('attr1');

                // Reset multiple attributes
                //this.model.reset(['attr1', 'attr2']);
        }
});

If you’ve worked with Backbone before, the above code will probably make sense. I’m basically storing the initial attributes during initializein this._originalAttributes. Then, on reset, looping through all of the current attributes to see if there was an original version (and that it was changed).

There are three options when calling the reset function (which can be see in the Backbone View):

  1. No parameters: this will attempt to reset all of the model’s attributes
  2. Single attribute: pass the attribute name (as a string)
  3. Multiple attributes: pass an array of attribute names (as strings)

If the server-state of a model is critical, this function could be rewritten to check if the model isNew() and use this._originalAttributes, or just call fetch().. Though resetting individual attributes wouldn’t work with fetch().

Update: I was recently introduced to Backbone.Memento, which does all of this plus more—I’d recommend checking it out!

Tagged:

Leave a Reply

Your email address will not be published. Required fields are marked *