【问题标题】:Custom validator for backbone.js validation用于backbone.js 验证的自定义验证器
【发布时间】:2016-04-22 11:35:01
【问题描述】:

我正在使用带有 backbone.validation plugin 的 Backbone.js 来构建一个 custom validator,以检查电子邮件地址(在表单输入中输入)是否已被占用。

新的验证器名为 emailAvailable,您可以在下面看到: (注意:它是 Coffescript,但在底部你会发现转换为标准 javascript 的代码)

# ==================================
#           MODELS 
# ==================================    
User = Backbone.Model.extend(

    urlRoot: "/user"

    validation:
        email:
            fn: "emailAvailable"

    emailAvailable: (value, attr, computedState) ->
       // Ajax call to server (Play framework 2.2.1): returns the string "email available" if it doesn't find the email and returns the email address if it find it
       checkEmail = $.ajax(jsRoutes.controllers.Signup.isEmailExists(value)) 
       checkEmail.done (msg) ->
         emailFound = msg
         if value is emailFound
           return "already taken"

       return
)

# ==================================
#           VIEWS 
# ==================================    
SignUpView = Backbone.View.extend(
    initialize: ->
        Backbone.Validation.bind(this)

    el: "body"

    events:
        "change     input"     :    "validateInput"

    validateInput: (event) ->
        input = $(event.currentTarget)
        inputName = event.currentTarget.name 
        inputValue = input.val()

        this.model.set(inputName, inputValue)
        if this.model.isValid(inputName)
            input.removeClass "error"
            input.addClass "valid"
        else
            input.removeClass "valid"
            input.addClass "error"
...

这不起作用,我不明白为什么。我哪里错了?

编辑:代码转换为javascript

var SignUpView, User;

User = Backbone.Model.extend({
  urlRoot: "/user",
  validation: {
    email: {
      fn: "emailAvailable"
    }
  },
  emailAvailable: function(value, attr, computedState) {
    var checkEmail;
    checkEmail = $.ajax(jsRoutes.controllers.Signup.isEmailExists(value));
    checkEmail.done(function(msg) {
      var emailFound;
      emailFound = msg;
      if (value === emailFound) {
        return "already taken";
      }
    });
  }
});

SignUpView = Backbone.View.extend({
  initialize: function() {
    return Backbone.Validation.bind(this);
  },
  el: "body",
  events: {
    "change     input": "validateInput"
  },
  validateInput: function(event) {
    var input, inputName, inputValue;
    input = $(event.currentTarget);
    inputName = event.currentTarget.name;
    inputValue = input.val();
    this.model.set(inputName, inputValue);
    if (this.model.isValid(inputName)) {
      input.removeClass("error");
      return input.addClass("valid");
    } else {
      input.removeClass("valid");
      return input.addClass("error");
    }
  }
});

【问题讨论】:

  • 这不是 JavaScript,请修复标签。
  • 看一下编辑,我已经把代码转成javascript了

标签: javascript validation backbone.js playframework coffeescript


【解决方案1】:

Backbone.Validation 很遗憾不支持异步验证功能。这基本上是默认主干验证流程的限制。它在设计时只考虑了同步验证方式。

你基本上有两个选择:

  • 为 ajax 调用指定 async:false 选项
  • 为此案例实施您自己的验证流程

我个人会选择选项 2,因为同步 ajax 调用会锁定浏览器,直到调用完成。

更新说明:

在我回答了这个问题后,我做了快速的谷歌搜索,看起来 Backbone.Validation 有扩展,它允许异步验证。请注意,我没有使用过,也没有以任何方式测试过它:)

链接:https://github.com/suevalov/async.backbone.validation

【讨论】:

  • 这个异步验证插件看起来很有前途,但是如何配置主干验证来使用它呢?文档只是链接回骨干验证。
【解决方案2】:

您必须自己执行异步验证功能。以下是无需任何插件的方法,只需一点逻辑和良好的旧编码即可。

1) 让我们从保存模型的函数开始。在保存发生之前,您将需要一个 Deferred 对象,如下所示:

this.asyncValidation = $.Deferred();

2) 然后你将不得不手动调用你自己的自定义验证函数:

this.model.asyncValidate();

3) 然后你将不得不等到你的异步验证完成。完成后,只需保存您的模型:

$.when(this.checkDuplicatesFinished).done(function () { 

4) 检查您自己的具有您自己的异步验证结果的模型属性:

if (self.model.asyncValidateOK) {

5) 保存您的模型:

self.model.save(); 

代码如下:

this.asyncValidation = $.Deferred();
this.model.asyncValidate(asyncValidation);
var self = this; 

$.when(this.checkDuplicatesFinished).done(function () { 
    if (self.model.asyncValidateOK) {
        self.model.save(); 
    }
});

现在,让我们看看您的模型。这是新的客户验证功能所在的位置。这非常简单,您需要一个布尔变量来存储验证结果和验证方法本身。

window.app.MyModel = Backbone.Model.extend({

    asyncValidateOK: true,
    asyncValidate: function (defferedObject) {
        var self = this;
        var attrs = this.attributes; // a copy of the params that are automatically passed to the original validate method
        $.get("someAsyncMethod", {}, function(result){

            // do your logic/validation with the results
            // and tell the referred object you finished
            if (true){ //validation ok (use your own logic)

                self.asyncErrors = []; // no errors
                self.asyncValidateOK = true;
                deferredObject.resolve();

            } else { // validation not ok

                self.asyncErrors.push(); 
                self.asyncValidateOK = false;
                deferredObject.resolve();

            }
        });
    }
});

更多文档请查看http://backbonejs.org/,但与此无关。希望这对最终尝试异步验证的任何人有所帮助。

【讨论】:

    猜你喜欢
    • 2013-07-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多