backbone.js验证的自定义验证器
我使用Backbone.js和backbone.validation plugin来构建custom validator,它检查是否已输入电子邮件地址(已输入表单输入)。backbone.js验证的自定义验证器
新的验证被称为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"
...
这不起作用我不明白为什么。我错在哪里?
EDIT:代码转换为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");
}
}
});
Backbone.Validation可悲不支持异步验证函数。这基本上是默认骨干验证流程的限制。它的设计只考虑了同步验证方式。
你已经基本上2种选择:
- 指定异步:对于AJAX调用
- 假选项实施这种情况下自己的验证流程
我个人使用选项2去,因为同步ajax调用将锁定浏览器直到调用完成。
更新注:
我做了快速谷歌搜索后,我回答了这个问题,它看起来像有扩展Backbone.Validation,允许非同步的验证。请注意,我没有用过,也没有以任何方式测试了它:)
这个异步验证插件看起来很有前途,但如何配置骨干验证以使用它?文档只是链接到骨干验证。 – DagR
你将不得不自己做你的异步验证功能。这里是你如何做到这一点,没有任何插件,只是一个小逻辑和良好的旧编码。
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/,但没有什么与此相关的。希望这有助于任何最终尝试异步验证的人。
这不是JavaScript,请修复标签。 – jgillich
看看编辑,我已将代码转换为javascript –