Javascript 带有knockout.js的自定义验证规则

Javascript 带有knockout.js的自定义验证规则,javascript,jquery,ajax,validation,knockout.js,Javascript,Jquery,Ajax,Validation,Knockout.js,我在使用knockout.js设置自定义验证规则以检查用户名是否已存在时遇到问题。根据我的理解,如果返回值为真,则不存在错误,否则将设置错误 自定义验证的一个示例 //val is the username in question and searchType is the type of search(username or email) function checkValue(val, searchType){ if(searchType == 'userName'){ $.po

我在使用knockout.js设置自定义验证规则以检查用户名是否已存在时遇到问题。根据我的理解,如果返回值为真,则不存在错误,否则将设置错误

自定义验证的一个示例

//val is the username in question and searchType is the type of search(username or email)
function checkValue(val, searchType){
  if(searchType == 'userName'){
    $.post("/users/check_if_exists",{ 'type':'username', 'value': val },function(data) {
        var info = JSON.parse(data);
        if(info.username_availability == "available"){
            return searchType;
                            //I know this is working because I've alerted the searchtype here and it displays properly
        }
        else{
            return "unavailable";
        }
    });
  }
} 

ko.validation.rules['checkIfExists'] = {
    validator: function (val, searchType) {
        return searchType == checkValue(val, searchType); //if the username is availble, the searchType is returned back so it would return searchType == searchType which should be true meaning there are no errors
    },
    message: 'This username is taken, please select another.'
};
ko.validation.registerExtenders();
我已经检查了网络选项卡,帖子返回了正确的值。如果该值可用,则返回searchType。这样,它会比较searchType==searchType,这应该是真的。然而,事实并非如此

有没有其他方法来完成我想做的事情

更新

这是我现在所拥有的

function checkValue(val, searchType, callback) {
     var callback = function(data) {
        return true;
    }
    $.post("/users/check_if_exists", { 'type':'username', 'value': val }, function(data) {
        info = JSON.parse(data);
        if(info.username_availability == "available"){
            callback(true);
        } else {
            callback(false);
        }
    }); 
}

ko.validation.rules['checkIfExists'] = {
    async: true,
    validator: function (val, searchType) {
        alert(checkValue(val, searchType));//returns undefined
        return checkValue(val, searchType);
    },
    message: 'This username is taken, please select another.'
};
ko.validation.registerExtenders();

您编写的checkValue始终返回未定义的值。从回调函数内部调用“return”仅设置该回调函数的返回值(而不是“outer函数”)。如果验证器函数要求立即返回值(就像knockout所做的那样),您将无法异步获取该数据。

正如您编写的checkValue一样,它总是返回未定义的值。从回调函数内部调用“return”仅设置该回调函数的返回值(而不是“outer函数”)。如果验证器函数要求立即返回值(就像knockout所做的那样),您将无法异步获取该数据。

让我将您的代码转换为更可读的代码:

function checkValue(val) {
    var callback = function(data) {
        return 'bar';
    }

    $.post('url', 'data', callback); 
}

var x = checkValue('foo');
您希望x设置为“bar”,但实际情况并非如此。 我将您的匿名函数替换为“callback”,以便您更好地理解从它返回的内容并不意味着“checkValue”将返回任何内容。 之后,下一个问题是AJAX调用是异步的

验证器函数接受三个参数:值、额外参数和回调函数。回调函数参数的设计正是为了在这种情况下为您提供帮助

在$.post的成功回调中,您只需为作为参数传递true/false的验证器函数调用该回调函数

function checkValue(val, params, callback) {
    $.post('url', 'data', function(data) {
        if(data === 'bar') {
            callback(true);
        } else {
            callback(false);
        }
    }); 
}

让我将您的代码转换为更具可读性的代码:

function checkValue(val) {
    var callback = function(data) {
        return 'bar';
    }

    $.post('url', 'data', callback); 
}

var x = checkValue('foo');
您希望x设置为“bar”,但实际情况并非如此。 我将您的匿名函数替换为“callback”,以便您更好地理解从它返回的内容并不意味着“checkValue”将返回任何内容。 之后,下一个问题是AJAX调用是异步的

验证器函数接受三个参数:值、额外参数和回调函数。回调函数参数的设计正是为了在这种情况下为您提供帮助

在$.post的成功回调中,您只需为作为参数传递true/false的验证器函数调用该回调函数

function checkValue(val, params, callback) {
    $.post('url', 'data', function(data) {
        if(data === 'bar') {
            callback(true);
        } else {
            callback(false);
        }
    }); 
}

验证调用您的验证函数。 关于将成功/失败状态传递回ko.validation的方式,有两种类型的验证函数:直接返回真/假的方式,或“异步”方式

异步方式的存在仅仅是因为$.ajax存在,基本上就是这样:在ajax响应返回到浏览器后,您必须以某种方式通知ko.validation,而不是返回值(这是不可能的,因为您使用的是$.ajax调用),对吗

所以编写这个库的聪明人用一个额外的参数调用你的验证函数,一个函数(回调),你必须在响应可用时调用它

function checkValue(val, searchType, callback){
  if(searchType == 'userName'){
    $.post("/users/check_if_exists",{ 'type':'username', 'value': val },function(data) {
        var info = JSON.parse(data);
        if(info.username_availability == "available"){
            callback(true);
                            //I know this is working because I've alerted the searchtype here and it displays properly
        }
        else{
            callback(false);
        }
    });
  }
} 


ko.validation.rules['checkIfExists'] = {
    async: true,
    validator: checkValue,
    message: 'This username is taken, please select another.'
};
ko.validation.registerExtenders();

验证调用您的验证函数。 关于将成功/失败状态传递回ko.validation的方式,有两种类型的验证函数:直接返回真/假的方式,或“异步”方式

异步方式的存在仅仅是因为$.ajax存在,基本上就是这样:在ajax响应返回到浏览器后,您必须以某种方式通知ko.validation,而不是返回值(这是不可能的,因为您使用的是$.ajax调用),对吗

所以编写这个库的聪明人用一个额外的参数调用你的验证函数,一个函数(回调),你必须在响应可用时调用它

function checkValue(val, searchType, callback){
  if(searchType == 'userName'){
    $.post("/users/check_if_exists",{ 'type':'username', 'value': val },function(data) {
        var info = JSON.parse(data);
        if(info.username_availability == "available"){
            callback(true);
                            //I know this is working because I've alerted the searchtype here and it displays properly
        }
        else{
            callback(false);
        }
    });
  }
} 


ko.validation.rules['checkIfExists'] = {
    async: true,
    validator: checkValue,
    message: 'This username is taken, please select another.'
};
ko.validation.registerExtenders();

那么,我有没有办法完成我想做的事情呢?那么,我有没有办法完成我想做的事情呢?不,没有,但是还有其他的解决办法。我已经在上面介绍了一个。另外,忘记了这一点,在验证规则定义(ko.validation.rules['checkIfExists']={…})中,您必须添加“async:true”。谢谢,取得了一些进展!我确保在文章之前添加了var callback=function(..),但我仍然无法让它正常工作。我试图发出警报(checkValue(val,searchType)),但未定义。我是不是应该把它设置为回调?什么不对?预期的结果还是我做这件事的方式?我更新了我原来的帖子来展示我现在拥有的东西。请看下面我的回复。同样,您的“checkValue”不会返回任何内容,但您希望它这样做。没有这样的事。AJAX意味着异步,这意味着代码在得到服务器响应之前不会停止执行,因此无法在同一个函数中“返回”某些内容。您需要某种形式的“睡眠”功能,JavaScript不允许这样做。不,不允许,但还有其他解决方案。我已经在上面介绍了一个。另外,忘记了这一点,在验证规则定义(ko.validation.rules['checkIfExists']={…})中,您必须添加“async:true”。谢谢,取得了一些进展!我确保在文章之前添加了var callback=function(..),但我仍然无法让它正常工作。我试图发出警报(checkValue(val,searchType)),但未定义。我是不是应该把它设置为回调?什么不对?预期的结果还是我做这件事的方式?我更新了我原来的帖子来展示我现在拥有的东西。请看下面我的回复。同样,您的“checkValue”不会返回任何内容,但您希望它这样做。没有这样的事。AJAX意味着异步,也就是说