How to report invalid form fields using Backbone.js
===

I'm using Backbone to manage the state of an HTML form. The Model's role is to handle validation. The View's role is to wrap the HTML form and respond to the `change` or `error` events emitted by the model.

Backbone seems to only emit `change` events when the given field is actually valid. This is causing some really unexpected behavior that makes me thing that I'm doing this wrong.

Here is a summary of what I'm doing:
1. Initial load serializes the form and injects it into the model
2. When an `error` event is emitted, I generate error nodes next to the invalid field.
3. When a `change` event is emitted, I remove the error notes next to the (now valid) field.

When a page is rendered with an initially valid form, and a user invalidates a field, the message is displayed as expected; however, the model never updates the field internally. Thus when the user corrects the error, a `change` event is never emitted. 

[Example: Initially valid](http://jsfiddle.net/BUJe6)

When a page is rendered with an initially *invalid* form, things appear to be working fine... but this is only because the model's initial attributes are empty. Correcting the field makes the messages disappear, but if you change it again to an invalid state, the message never disappears. 

[Example: Initially invalid](http://jsfiddle.net/BUJe6/1)

What am I doing wrong? Perhaps there's another approach I should be using instead?

### My Model

    var Foo = Backbone.Model.extend({
        validate: function(attr) {
            var errors = {};

            if (_.isEmpty(attr)) return;

            if (attr.foo && attr.foo != 123) {
                errors.foo = ['foo is not equal to 123'];
            }

            if (attr.bar && attr.bar != 456) {
                errors.bar = ['bar is not equal to 456'];
            }

            return _.isEmpty(errors) ? undefined : errors;
        }
    });

### My View

    FooForm = Backbone.View.extend({
        events: {
            'change :input': 'onFieldChange'
        },

        initialize: function(options) {
            this.model.on('error', this.renderErrors, this);
            this.model.on('change', this.updateFields, this);

            // Debugging only
            this.model.on('all', function() {
                console.info('[Foo all]', arguments, this.toJSON())
            });

            this.model.set(this.serialize());
        },

        onFieldChange: function(event) {
            var field = event.target,
                name = field.name,
                value = field.value;

            this.model.set(name, value);
        },

        renderErrors: function(model, errors) {
            _.each(errors, function(messages, fieldName) {
                var el = $('#' + fieldName),
                    alert = $('<div/>').addClass('error');

                el.parent().find('.error').remove();

                _.each(messages, function(message) {
                    alert.clone().text(message).insertAfter(el);
                });
            });
        },

        updateFields: function(model, options) {
            if (!options || !options.changes) return;

            _.each(_.keys(options.changes), function(fieldName) {
                var el = $('#' + fieldName);

                el.parent().find('.error').remove();
            });
        },

        serialize: function() {
            var raw = this.$el.find(':input').serializeArray(),
                data = {},
                view = this;

            $.each(raw, function() {
                // Get the model's field name from the form field's name
                var name = this.name;

                if (data[name] !== undefined) {
                    if (!data[name].push) {
                        data[name] = [data[name]];
                    }

                    data[name].push(this.value || '');
                }
                else {
                    data[name] = this.value || '';
                }
            });
            return data;

        }
    });
