2012-06-16 17 views
13

मेरे पास एक पृष्ठ है जो HTML5 सेट कस्टम वर्चुअल() विधि [पुराने ब्राउज़र के लिए webshims लाइब्रेरी का उपयोग करके] अगले पृष्ठ पर जारी रखने से पहले एक ईमेल का AJAX सत्यापन करता है।मैं एक jQuery ब्लॉकिंग AJAX कॉल को async = false के बिना कैसे करूं?

इसके लिए काम करने के लिए, मैंने एजेक्स विकल्प को $ .ajax() कॉल में सिंक्रोनस बनाने के लिए सेट किया है, जो AJAX प्रतिक्रिया के लंबित पृष्ठ को अवरुद्ध कर रहा है, अन्यथा फॉर्म AJAX कॉल रिटर्न से पहले प्रस्तुत करता है, सत्यापन अप्रभावी।

<script> 
    function validateEmailRegistered(input) { 
    if (input.setCustomValidity === undefined) return; 
    var err = 'Email address not found'; 
    $.ajax({ 
     url: 'email-is-registered.php', 
     data: { email: input.value }, 
     async: false, 
     success: function(data) { 
     var ok = data=='true'; 
     input.setCustomValidity(ok ? '' : err) 
     } 
    }); 
    } 
</script> 

<form method="get" action="nextpage.php"> 
    <input name="email" id="email" type="email" required 
    onChange="validateEmailRegistered(this)"> 
    <button type="submit">go</button> 
<form> 

मुझे लगता है कि async विकल्प को jQuery 1.8 के रूप में बहिष्कृत किया जाना है।

मैं कैसे async विकल्प के बिना इस अवरुद्ध कार्रवाई प्राप्त कर सकते हैं?

+0

आप किस समाधान का उपयोग कर समाप्त कर चुके हैं? मुझे एक ही समस्या का सामना करना पड़ रहा है। –

उत्तर

0

मुझे लगता है कि आप किसी भी तरह सबमिट करने पर पूर्ण फॉर्म सत्यापन कर रहे होंगे, तो शायद यह कोई समस्या नहीं है कि आपके द्वारा टाइप की गई ईमेल सत्यापन में बाधा आती है, और फॉर्म सबमिशन को प्राथमिकता दी गई है।

मुझे लगता है कि मुझे क्या करना चाहते हैं क्या 'validateEmailRegistered' AJAX अनुरोध निरस्त किया जाता है जब उपयोगकर्ता प्रपत्र सबमिट करता। फिर, सामान्य रूप से पूर्ण सर्वर-साइड फॉर्म सत्यापन पूर्ण करें - ईमेल सत्यापन सहित।

के रूप में आप प्रकार सत्यापन के मेरे समझ है कि यह एक लालित्य, प्रपत्र मान्य है जब यह प्रस्तुत की है के लिए नहीं एक विकल्प है। इसलिए फ़ॉर्म सबमिशन को अवरुद्ध करने के लिए मुझे यह समझ में नहीं आता है।

+0

मैं सर्वर-साइड सत्यापन भी कर रहा हूं, लेकिन यह अवरुद्ध AJAX कॉल की तुलना में गरीब उपयोगकर्ता इंटरैक्शन प्रदान करता है जो नियमित (सेट कस्टम वर्चस्व) तंत्र के माध्यम से उपयोगकर्ता फ़ीडबैक प्रदान करता है। क्लाइंट-साइड सत्यापन सर्वर-साइड सत्यापन के लिए एक विकल्प नहीं है, लेकिन बेहतर उपयोगकर्ता अनुभव प्रदान करता है। एक सर्वर-साइड त्रुटि संदेश अवरुद्ध करने का एक और तरीका है, वास्तव में ... – ChrisV

0

मुझे लगता है कि आपको थोड़ा सा बदलाव करना होगा कि यह कैसे काम करता है। अवरुद्ध करने की कोशिश मत करो, लेकिन गैर-अवरुद्ध गले लगाओ।

मैं इस तरह करना होगा: - ईमेल पर मान्यता रखें; इसे असीमित बनाओ। जब यह मान्य हो, तो एक चर में कहीं ध्वज सेट करें ताकि यह पता चल सके कि यह ठीक है। - यह जांचने के लिए form.submit() पर एक कॉलबैक जोड़ें कि यह ईमेल ठीक है (चर के साथ) और सबमिशन को रोकें यदि यह नहीं है।

इस तरह आप वेब ब्राउज़र यूआई फ्रीज बिना अतुल्यकालिक कॉल रख सकते हैं।

- [संपादित करें] -

यह कुछ त्वरित कोड मैं सिर्फ क्या आपके पास पहले से आधार पर उदाहरण के लिए लिखा है।

आपकी जानकारी के लिए, एक प्रोग्रामिंग धारणा "वादों" कहा जाता है वास्तव में समस्या आप को हल करने का आविष्कार किया गया है (वायदा और आस्थगित अन्य शब्दों इसके लिए कर रहे हैं)।

यहाँ यह क्या है और कैसे (डोजो या jQuery का उपयोग) जावास्क्रिप्ट में उन्हें इस्तेमाल करने पर एक लेख है: http://blogs.msdn.com/b/ie/archive/2011/09/11/asynchronous-programming-in-javascript-with-promises.aspx

<script> 
    function validateEmailRegistered(input) { 
    if (input.setCustomValidity === undefined) return; 
    var err = 'Email address not found'; 
    $.ajax({ 
     url: 'email-is-registered.php', 
     data: { email: input.value }, 
     success: function(data) { 
     var ok = data=='true'; 
     input.setCustomValidity(ok ? '' : err); 
     // If the form was already submited, re-launch the check 
     if (form_submitted) { 
      input.form.submit(); 
     } 
     } 
    }); 
    } 

    var form_submitted = false; 

    function submitForm(form) { 
    // Save the user clicked on "submit" 
    form_submitted = true; 
    return checkForm(form); 
    } 

    function checkForm(form, doSubmit) { 
    if (doSubmit) { 
     form_submitted = true; 
    } 
    // If the email is not valid (it can be delayed due to asynchronous call) 
    if (!form.email.is_valid) { 
     return false; 
    } 
    return true; 
    } 
</script> 

<form method="get" action="nextpage.php" onsumbit="return submitForm(this);"> 
    <input name="email" id="email" type="email" required 
    onChange="validateEmailRegistered(this)"> 
    <button type="submit">go</button> 
<form> 
+0

सबमिशन को रोकने के लिए जमा फॉर्म पर कॉलबैक का उपयोग करना ठीक है जो मैं प्राप्त करना चाहता हूं, लेकिन मुझे नहीं लगता कि कॉलबैक अगर मैं इसे कैसे कर सकता हूं एसिंक्रोनस है ... – ChrisV

0

तुम सच में दे नहीं उन्हें प्रपत्र सबमिट जब तक आप जाँच कर ली है पर सेट कर रहे हैं ईमेल वैधता, disabled विशेषता के साथ अपना सबमिट बटन शुरू करें, फिर कॉलबैक सेट $('form button').removeAttr('disabled');

कहा जा रहा है कि, मैं अन्य लोगों के साथ हूं - बस उन्हें फ़ॉर्म सबमिट करने दें! आम तौर पर लोग इसे सही पाते हैं और आप उन्हें बिना किसी त्रुटि के पारित करते हैं ...

0

आप इसे असीमित रूप से कर सकते हैं।

एक वैश्विक चर बनाएँ, मैं इसे ajax_done_and_successful_flag, कहता हूं कि आप प्रोग्राम की शुरुआत में झूठी शुरुआत करते हैं। आप अपने अजाक्स फ़ंक्शन जैसेफ़ंक्शन या आपके अजाक्स त्रुटि फ़ंक्शन जैसे विभिन्न स्थानों पर इसे सत्य या गलत पर सेट करेंगे।

फिर आपको अपने फ़ंक्शन मान्य करने के नीचे सबमिट हैंडलर जोड़ने की आवश्यकता है।

submitHandler: function(form) { 
    if (ajax_done_and_successful_flag === true) { 
    form.submit() 
    } 
} 

समस्या यह है कि कोड एक रैखिक तरीके से निष्पादित नहीं हो रहा है।
अपने कोड में फायरबग के console.log स्टेटमेंट का एक गुच्छा रखो।
निष्पादन के अनुक्रम का निरीक्षण करें। आप देखेंगे कि आपका
अजाक्स प्रतिक्रिया पिछली बार वापस आ जाएगी, या जब भी ऐसा लगता है।
यही कारण है कि सबमिट सबमिट करने से पहले सही अजाक्स
परिणाम के लिए मान्य फ़ंक्शन को मजबूर करने के लिए आपको सबमिट हैंडलर और वैश्विक ध्वज
की आवश्यकता है।

अजाक्स प्रतिक्रिया से स्क्रीन करने के लिए किसी भी उत्पादन, ऐसी सफलता समारोह और त्रुटि समारोह के रूप में अजाक्स कार्यों में किया जाना है, जरूरत है।
आपको वैध स्थान की सफलता/त्रुटि फ़ंक्शंस के रूप में उसी स्थान पर लिखना होगा।
इस तरह अजाक्स त्रुटि संदेश वैध फ़ंक्शन के त्रुटि फ़ंक्शन के साथ मिश्रित होते हैं।
यह अवधारणा थोड़ा मुश्किल लग सकती है।
विचार को ध्यान में रखना है कि सत्यापित करें समारोह में सफलता और त्रुटि कार्यों सफलता और अजाक्स कॉल में त्रुटि कार्यों के रूप में एक ही स्थान पर लिख रहे हैं, और कहा कि ठीक है, वह यह है कि कैसे यह होना चाहिए हो।
मेरे त्रुटि संदेशों का स्थान उपयोगकर्ता इनपुट प्रकार के बगल में है। यह एक अच्छा उपयोगकर्ता अनुभव बनाता है जो मुझे लगता है कि आप पूछ रहे हैं।

यहां मेरा कोड नमूना है। मैंने इसे सरल बना दिया।

मैं jQuery-1.7.1
और jQuery सत्यापन प्लग में चला रहा हूँ 1.6
मैं फ़ायरफ़ॉक्स 14.0.1 का उपयोग कर रहा हूँ और मैं भी सफलतापूर्वक क्रोम 21.0 पर यह की कोशिश की।

var ajax_done_and_successful_flag = false; 

// Add methods 
    ... 

$.validator.addMethod("USERNAME_NOT_DUPLICATE", function (value, element) { 
    return this.optional(element) || validate_username_not_duplicate(); 
    }, 
    "Duplicate user name."); 

// validate 
$(document).ready(function () { 
    $('#register_entry_form form').validate({ 
     rules: { 
     username: { 
     required: true, 
     minlength: 2, 
     maxlength: 20, 
     USERNAME_PATTERN: true, 
     USERNAME_NOT_DUPLICATE: true 
     },  
    ... 
    errorPlacement: function (error, element) { 
     element.closest("div").find(".reg_entry_error").html(error); 
    }, 
    success: function(label) { 
     label.text('Success!'); 
    } , 

    submitHandler: function(form) { 
     if (ajax_done_and_successful_flag === true) {  
      form.submit(); 
     } 
    } 
    }); 
}); 

/* validation functions*/ 

function validate_username_not_duplicate() { 

    var username_value = $('#username').val(); // whatever is typed in 

    $.ajax({ 
     url: "check_duplicate_username.php", 
     type: "POST", 
     data: { username: username_value }, 
     dataType: "text", 
     cache: false, 
     //async: false, 
     timeout: 5000, 
     error: function (jqXHR, errorType, errorMessage) { 
     ajax_done_and_successful_flag = false; 

     if (errorType === "timeout") { 
      $('#username').closest("div").find(".reg_entry_error").html("Server timeout, try again later"); 
     } else if ... 

     }, 

     success: function (retString, textStatus,jqXRH) { 

     if (retString === "yes") { // duplicate name 
      // output message next to input field   
      $('#username').closest("div").find(".reg_entry_error").html("Name already taken."); 
      ajax_done_and_successful_flag = false; 
     } else if (retString === "no") { // name is okay 
      // output message next to input field 
      $('#username').closest("div").find(".reg_entry_error").html("success!"); 
      ajax_done_and_successful_flag = true; 

     } else { 
      console.log("in validate_username_duplicate func, success function, string returned was not yes or no."); 
      $('#username').closest("div").find(".reg_entry_error").html("There are server problems. Try again later."); 
      ajax_done_and_successful_flag = false; 
     } 
    } // end success function 

    }); // end ajax call 


    return true; // automatically return true, the true/false is handled in 
       // the server side program and then the submit handler 

} 

reg_entry_error पाठ इनपुट के बगल में जगह है। यहां फॉर्म का सरलीकृत कोड नमूना है।

<label class="reg_entry_label" for="username">Username</label> 
    <input class="reg_entry_input" type="text" name="username" id="username" value="" /> 
    <span class="reg_entry_error" id="usernameError" ></span> 

मुझे आशा है कि यह आपके प्रश्न का उत्तर देगा।

1

jQuery 1.8 के रूप में, async के उपयोग: jqXHR ($ .Deferred) के साथ झूठे पदावनत है; आपको पूर्ण/सफलता/त्रुटि कॉलबैक का उपयोग करना होगा।

http://api.jquery.com/jQuery.ajax/ (async अनुभाग)

मैं इस पाया थोड़ा परेशान ... डेवलपर्स दी जानी चाहिए पसंदasync: false साथ एक अवरुद्ध कॉल करता है, तो इसके कुछ मंच की अनुमति देता है बनाने के लिए - क्यों यह प्रतिबंधित? मैं बस एक लटकने के प्रभाव को कम करने के लिए एक टाइमआउट सेट करना होगा।

फिर भी, मैं अब 1.8 में एक कतार का उपयोग कर रहा हूं, जो गैर-अवरुद्ध है, और काफी अच्छी तरह से काम करता है। सेबेस्टियन रोच ने उपयोगिता का उपयोग करने में आसान बनाया है जो आपको कार्यों को कतारबद्ध करने और उन्हें चलाने/रोकने की अनुमति देता है। https://github.com/mjward/Jquery-Async-queue

queue = new $.AsyncQueue(); 
    queue.add(function (queue) { ajaxCall1(queue); }); 
    queue.add(function (queue) { ajaxCall2(queue); }); 
    queue.add(function() { ajaxCall3() }); 
    queue.run(); 

पहले 2 कार्यों में मैं कॉल में queue वस्तु गुजरती हैं, यहां कॉल की तरह लग रहे हैं क्या करना है:

function ajaxCall1(queue) { 
    queue.pause(); 
    $.ajax({ 
     // your parameters .... 
     complete: function() { 
     // your completing steps 
     queue.run(); 
     } 
    }); 
} 

// similar for ajaxCall2 

सूचना प्रत्येक कार्य की शुरुआत में queue.pause();, और queue.run() अपने complete कथन के अंत में कतार निष्पादन जारी रखने के लिए।

+0

यह अच्छा लग रहा है लेकिन लिंक मर चुका है :( – Gus

+1

@Gus के सिर के लिए धन्यवाद, मैंने googled और पाया कि परियोजना एक अलग github खाते में ले जाया गया। – sonjz

10

http://bugs.jquery.com/ticket/11013#comment:40

तुल्यकालिक ajax अनुरोध में स्थगित/वादा कार्यक्षमता के उपयोग 1.8 में पदावनत किया गया है। Async के साथ $ .ajax विधि: झूठी समर्थित है लेकिन आपको .then या .done जैसे वादा विधि के बजाय कॉलबैक पैरामीटर का उपयोग करना होगा।

तो, यदि आप सफलता/पूर्ण/त्रुटि हैंडलर का उपयोग कर रहे हैं, तो भी आप async:false का उपयोग कर सकते हैं। ऊपर jquery टिकट पर अधिक जानकारी।

संबंधित मुद्दे