2012-06-30 39 views
1

所以這是我的問題。修復了一個延遲的回調,導致在jQuery驗證w/jQuery Mobile PhoneGap中的錯誤錯誤

我目前正在使用jQuery Mobile和Validation jQuery插件進行表單驗證的PhoneGap應用程序。

我想設置一個自定義規則,以便它將檢查名稱是否已經在數據庫中,如果是,則阻止提交表單直到用戶選擇唯一的名稱。

這個問題是我以前遇到過的,但還沒有設法解決。當我調用執行SQL select語句的方法時,直到驗證器完成並拋出false後,成功回調纔會完成。這意味着如果用戶輸入一個唯一的名稱,它將顯示一個錯誤,但是如果用戶強制它重新驗證這些字段,那麼它將是有效的,因爲成功回調在此期間已經完成。

下面是相關代碼:

var nameUnique; 

jQuery.validator.addMethod("nameIsUnique", function(value, element) { 
     checkNameSQL(); 
     return this.optional(element) || nameUnique; 
    }, "This name is already in use. Please choose another."); 

$('#createForm').validate({ 
    rules: { 
     createName: { 
     required: true, 
     nameIsUnique: true 
     }, 
     createDescription: { 
     required: true 
     } 
    }, 
    //snip// 
}); 

function checkNameSQL() 
{ 
var name = document.forms['createForm'].elements['createName'].value; 
if (!(name == null || name == "")) 
{ 
    dbShell.transaction(function(tx) { 
     tx.executeSql("SELECT STATEMENT",[name],function(tx,results){if(results.rows.length==0){nameUnique = true;}},errorHandler) 
    },errorHandler); 
} 
} 

它是有道理的,切割出的問題不相關的代碼,我已經簡化它。正如你所看到的,我調用方法來檢查名稱是否存在,但在成功回調函數觸發器將nameUnique設置爲true之前,它將由驗證器返回,導致錯誤。

我該如何更改我的代碼以防止發生這種情況?我應該遵循什麼樣的通用編程做法來規避將來類似的問題?謝謝!

+0

應該不是你的'checkNameSQL'函數返回的東西了'addMethod()'方法?否則,後者如何知道SQL查詢的結果?無論如何,由於SQL查詢是一個異步事件,返回一個值將會很困難。這是一個同步性問題。看看jQuery的延期對象 - 這將是最簡單的解決方案。 – Utkanos

+0

目前,'executeSQL'的成功回調檢查結果是否爲空(如果是,那麼沒有匹配),並將驗證器檢查的變量設置爲true。只要我能說出來,將「返回真實」置於原位就什麼也不做。我會看看延期的對象,謝謝。 –

+0

我剛在其他問題的答案上發佈了一些資源 - 請參閱http://stackoverflow.com/questions/11278018/how-to-execute-a-javascript-function-only-after-multiple-other-functions- have-co/11278038#11278038 – Utkanos

回答

1

除了true和false之外,您可以返回pending作爲addMethod()的值,可用於延遲驗證。欲瞭解更多信息,你可以檢查驗證庫source

試試這個方法:

$.validator.addMethod("nameIsUnique", function(value, element) { 
    var validator = this; 
    var previous = this.previousValue(element); 
    checkNameSQL(value, function(status) { 
     var valid = status === true; 
     if (valid) { 
      var submitted = validator.formSubmitted; 
      validator.prepareElement(element); 
      validator.formSubmitted = submitted; 
      validator.successList.push(element); 
      validator.showErrors(); 
     } else { 
      var errors = {}; 
      var message = status || validator.defaultMessage(element, "remote"); 
      errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; 
      validator.showErrors(errors); 
     } 
     previous.valid = valid; 
     validator.stopRequest(element, valid); 
    }); 
    return "pending"; 
}, "This name is already in use. Please choose another."); 

function checkNameSQL(name, callback) { 
    if (!(name == null || name == "")) { 
     dbShell.transaction(function(tx) { 
      tx.executeSql("SELECT STATEMENT", [name], function(tx, results) { 
       if (results.rows.length == 0) { 
        nameUnique = true; 
        callback(true); 
       }else{ 
        callback(false); 
       } 
      }, errorHandler) 
     }, errorHandler); 
    } 
} 

對於演示檢查此琴 - http://jsfiddle.net/dhavaln/GqsVt/

+0

只做了一些快速測試,它的工作。輝煌!謝謝您的幫助。 但是如果我沒有問你是否可以解釋一下,我會失職,因爲使用我無法完全遵循的代碼沒有意義。有一些我不完全熟悉的語法。即,這3行: 'var valid = status === true;' 'var message = status || validator.defaultMessage(element,「remote」);' 'errors [element.name] = previous.message = $ .isFunction(message)?消息(value):message;' 你能解釋一下這幾行是什麼意思嗎?我以前看過一些語法,但我還不知道。再次感謝! –

+0

'var valid = status === true;',僅當狀態是布爾變量或狀態未定義時纔將'status'的值賦給'valid' – dhaval

+0

'var message = status || validator.defaultMessage(element,「remote」);',捕獲開發人員爲驗證失敗或遠程狀態設置的消息。在源文件中,消息映射也有一個「remote」字段。 – dhaval