backbone.js - 如何使用 Backbone.js 报告无效的表单字段

标签 backbone.js validation

我正在使用 Backbone 来管理 HTML 表单的状态。模型的作用是处理验证。 View 的作用是包装 HTML 表单并响应模型发出的 changeerror 事件。

Backbone 似乎只在给定字段实际有效时才发出 change 事件。这导致了一些非常意外的行为,让我觉得我做错了。

以下是我正在做的事情的总结: 1.初始加载序列化表单并将其注入(inject)到模型中 2. 当 error 事件发出时,我在无效字段旁边生成错误节点。 3. 当发出 change 事件时,我删除了(现在有效的)字段旁边的错误说明。

当页面以最初有效的形式呈现,并且用户使字段无效时,消息将按预期显示;但是,该模型从不在内部更新该字段。因此,当用户更正错误时,永远不会发出 change 事件。

Example: Initially valid

当页面以初始无效 形式呈现时,事情似乎工作正常......但这只是因为模型的初始属性为空。更正字段会使消息消失,但如果再次将其更改为无效状态,则消息永远不会消失。

Example: Initially invalid

我做错了什么?也许我应该改用另一种方法?

我的模型

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;
    }
});

我的看法

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;

    }
});

最佳答案

您无法使用 native Backbone 验证来验证单个字段。

在我的应用程序中,我使用了这个验证插件:https://github.com/thedersen/backbone.validation

然后在您的模型中为每个字段添加验证规则(这是可选的,因此您不需要将其添加到所有模型):

var NewReview = Backbone.Model.extend({
  initialize: function() {
     /* ... */
  },

  validation: {
    summary: {
      required: true,
      minLength: 10
    },
    pros: {
      required: true,
      minLength: 10
    },
    cons: {
      required: true,
      minLength: 10
    },
    overall: function(value) {
      var text = $(value).text().replace(/\s{2,}/g, ' ');
      if (text.length == 0) text = value;
      if (text.length < 20) return "Overall review is too short";
    },
    rating: {
      range: [0.5, 5]
    },
    product_id: {
      required: true
    }
  }
});

与在 View 或其他地方相比,您可以验证整个模型或单个字段:

if (this.model.validate()) { ... }

if (this.model.isValid("summary")) { ... }

关于backbone.js - 如何使用 Backbone.js 报告无效的表单字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11403586/

相关文章:

Backbone .js - 我如何获取本地或服务器数据

asp.net - 验证器 - 一次显示一个错误

java - Hibernate 验证——与其他对象比较

javascript - 如何使用 JavaScript 验证 YouTube 视频 ID

javascript - Wordpress - Gravity Forms - 如何启用 JavaScript 验证?

ruby-on-rails-3 - 接受导轨使用条款

dom - 将其他 DOM 元素添加到 Backbone 中的 View

backbone.js - 如何获取用户输入数据的值(value)?

jquery - Backbone 模型 CORS 获取未发送

javascript - 为什么我的 javascript Backbone.js 模型共享其父类的相同 "instance"?