【问题标题】:Custom validation rule with knockout.js带有 knockout.js 的自定义验证规则
【发布时间】:2013-08-23 06:12:01
【问题描述】:

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

Here's 自定义验证示例

//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();

我检查了网络选项卡,POST 正在返回正确的值。如果该值可用,则返回 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();

【问题讨论】:

    标签: javascript jquery ajax validation knockout.js


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 谢谢,成功了!你为我清理了很多,我真的很感激。
    【解决方案2】:

    让我把你的代码变成更易读的东西:

    function checkValue(val) {
        var callback = function(data) {
            return 'bar';
        }
    
        $.post('url', 'data', callback); 
    }
    
    var x = checkValue('foo');
    

    您希望 x 设置为 'bar',但事实并非如此。 我用“回调”替换了你的匿名函数,所以你更好地理解从它返回的东西并不意味着“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.rules['checkIfExists'] = {...}) 你必须添加“async: true”。
    • 谢谢,取得了一些进展!我确保在帖子之前添加 var callback = function(....) ,但我似乎仍然无法让它工作。我试图 alert(checkValue(val, searchType)) 但未定义。我应该以某种方式将其设置为等于回调吗?
    • 哪里不对?预期的结果或我正在做的方式?我更新了我的原始帖子以显示我现在拥有的内容。
    • 请参阅下面的回复。同样,您的“checkValue”不会返回任何内容,但您希望它会这样做。哪有这回事。 AJAX 意味着异步,这意味着代码在获得服务器响应之前不会停止执行,因此您无法在同一函数中“返回”某些内容。您需要某种形式的“睡眠”功能,而 JavaScript 不允许这样做。
    【解决方案3】:

    checkValue 正如你所写的,它总是返回未定义的。从回调函数内部调用“return”只会设置该回调函数(而不是“外部函数”)的返回值。如果验证器函数需要立即返回值(就像淘汰赛似乎所做的那样),您将无法异步获取该数据。

    【讨论】:

    • 那么有什么方法可以完成我想做的事情吗?
    猜你喜欢
    • 1970-01-01
    • 2017-07-25
    • 2018-07-29
    • 2017-04-11
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2019-02-12
    相关资源
    最近更新 更多