2013-08-22 192 views
0

我無法獲得自定義驗證規則設置與knockout.js檢查用戶名是否已經存在。根據我的理解,如果返回是真的,那麼就沒有錯誤,否則就會設置錯誤。自定義驗證規則與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("https://stackoverflow.com/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,它應該是true。但是,事實並非如此。

有沒有其他方法可以完成我想要做的事情?

更新

這裏是我的現在,你已經寫它總是返回undefined

function checkValue(val, searchType, callback) { 
    var callback = function(data) { 
     return true; 
    } 
    $.post("https://stackoverflow.com/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(); 

回答

2

ko.validation調用您的驗證函數。 關於它們將成功/失敗狀態傳遞迴ko.validation的方式,有兩種類型的驗證函數:直接返回true/false方式或「異步」方式。

異步方式的存在只是因爲$ .ajax存在,它基本上就是這樣:不是返回一個值(這是不可能的,因爲你使用$ .ajax調用),你必須以某種方式通知ko.validation後Ajax響應回到瀏覽器,對吧?

所以編寫這個庫的聰明人會用一個額外的參數,一個函數(回調函數)來調用你的驗證函數,當響應可用時你必須調用它。

function checkValue(val, searchType, callback){ 
    if(searchType == 'userName'){ 
    $.post("https://stackoverflow.com/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(); 
+0

謝謝,得到它的工作!你爲我清理了很多,我非常感激。 – user1443519

0

校驗值的。從回調函數內部調用「return」僅設置該回調函數的返回值(而不是「外部函數」)。如果驗證器函數馬上要求返回值(如同敲除操作一樣),那麼您將無法異步獲取該數據。

+0

那麼有什麼辦法可以完成我想要做的事嗎? – user1443519

1

讓我把你的代碼更具可讀性:

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

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

var x = checkValue('foo'); 

你期望X設置爲「巴」時情況並非如此。 我用「回調」取代了你的匿名函數,所以你更好理解,從它返回的東西並不意味着「checkValue」將返回任何東西。 之後,你的下一個問題是AJAX調用是異步的。

驗證器函數接受三個參數:值,額外參數和回調函數。回調函數參數旨在幫助您處理這種情況。

在$ .post的成功回調中,您只需將驗證器函數的回調函數作爲參數傳遞true/false即可。

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

不,它不是,但有其他解決方案。我在上面提出了一個。 –

+0

此外,在驗證規則定義(ko.validation.rules ['checkIfExists'] = {...})你必須添加「async:true」。 –

+0

謝謝,取得一些進展!我確保在發佈之前添加var callback = function(....),但我似乎無法使其工作。我試圖提醒(checkValue(val,searchType))但未定義。我是否應該設置它等於回調? – user1443519