2013-08-22 4 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, который должен быть правдой. Однако это не так.

Есть ли другой способ выполнить то, что я пытаюсь сделать?

обновление

Вот что у меня есть, как сейчас

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 или «async».

Асинхронный путь существует только потому, что существует $ .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

checkValue, как вы написали, что всегда возвращает неопределенное значение. Вызов «return» изнутри функции обратного вызова устанавливает только возвращаемое значение для этой функции обратного вызова (а не «внешняя функция»). Если функция валидатора сразу же вернет значение возврата (как это делает нокаут), вы не сможете получить эти данные асинхронно.

+0

Так можно ли каким-либо образом выполнить то, что я пытаюсь сделать? – user1443519

1

Позвольте мне превратить ваш код в нечто более читаемым:

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

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

var x = checkValue('foo'); 

Вы ожидаете х быть установлен в «бар», когда это не так. Я заменил вашу анонимную функцию «обратным вызовом», чтобы вы лучше поняли, что возврат чего-то от нее не означает, что «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

Смежные вопросы