2013-05-10 2 views
6

मुझे सर्वर से सभी प्रतिक्रियाओं में एक संभावित लॉगिन पेज पकड़ने की आवश्यकता है, इसलिए मैंने वैश्विक रूप से Backbone.sync को ओवरराइड कर दिया है, इसलिए मैं उन्हें पास करने से पहले सभी त्रुटियों की जांच कर सकता हूं।बैकबोन सिंक त्रुटियों को पकड़ना

Backbone.originalSync = Backbone.sync; 

Backbone.sync = function (method, model, options) { 
    var originalSuccess, originalError; 
    console.log("sync override..."); 
    // remember original success so we can call it if user logs in successfully 
    originalSuccess = options.success; 
    // proxy the error callback to first check if we get a login page back 
    originalError = options.error; 
    options.error = function (model, xhr, options) { 
     if (xhr.status === 200 && xhr.responseText === "") { 
      // parse error from empty response (jq1.9 invalid json, ok) 
      originalSuccess(model, xhr, options); 
     } else { 
      console.log("Sync error " + statusTxt + ", " + thrown.message); 
      if (xhr.status === 200 || xhr.status === 302 || xhr.status === 0) { 
       // login page returned instead of json... 
       // open a new window with relogon.html to trigger a new login 
       window.showModalDialog("../relogon.html"); 
      } else { 
       // normal error, pass along 
       if (originalError) { 
        originalError(model, xhr, options); 
       } 
      } 
     } 
    }; 

    // call the original sync 
    Backbone.originalSync(method, model, options); 
}; 

यह 0.9.9 से 1.0 तक जाने पर बुरी तरह टूट गया। ऐसा लगता है कि मूल Backbone.sync अलग-अलग त्रुटि वाले हैंडलर को अलग करता है, जिससे मेरी त्रुटि हैंडलर को पहले jquery xhr हस्ताक्षर के साथ बुलाया जा सकता है। मैं इस के लिए त्रुटि हैंडलर के हस्ताक्षर बदलना पड़ा:

options.error = function (xhr, statusTxt, thrown) { 

ठीक है अब तो यह काम करता है, लेकिन मैं लग रहा है कि मैंने कुछ गलत कर रहा हूँ मिलता है।

क्या ऐसा करने का कोई बेहतर तरीका है?

मैंने jquery वादों के साथ प्रयास किया लेकिन मुझे त्रुटि स्थिति से सफलता (जब मूल Success को कॉल करते समय) स्विच करने में सक्षम होना चाहिए, जो वादे के साथ काम नहीं कर रहा था।

+0

क्या आप अपना jQuery प्रयास दिखा सकते हैं? यह वादा [एसआईसी] लगता है। –

उत्तर

8

आप अपनी खुद की jQuery Deferred object निर्माण कर सकते हैं डिफ़ॉल्ट Backbone.sync व्यवहार

Backbone.sync = function (method, model, opts) { 
    var xhr, dfd; 

    dfd = $.Deferred(); 

    // opts.success and opts.error are resolved against the deferred object 
    // instead of the jqXHR object 
    if (opts) 
     dfd.then(opts.success, opts.error); 

    xhr = Backbone.originalSync(method, model, _.omit(opts, 'success', 'error')); 

    // success : forward to the deferred 
    xhr.done(dfd.resolve); 

    // failure : resolve or reject the deferred according to your cases 
    xhr.fail(function() { 
     if (xhr.status === 200 && xhr.responseText === "") { 
      dfd.resolve.apply(xhr, arguments); 
     } else { 
      if (xhr.status === 200 || xhr.status === 302 || xhr.status === 0) { 
       console.log('login'); 
      } 
      dfd.reject.apply(xhr, arguments); 
     } 
    }); 

    // return the promise to add callbacks if necessary 
    return dfd.promise(); 
}; 

वादा अंत राज्य आप चुनते हैं दर्शाता है को बदलने के लिए।

http://jsfiddle.net/AsMYQ/4/ एक विफल डेमो के लिए, http://jsfiddle.net/AsMYQ/5/ सफलता के लिए।

और अगर मैं

  • आप शायद अपनी प्रवेश से निपटने के साथ इतना कसकर Backbone.sync टाई नहीं करना चाहिए सकता है। @Andrey के रूप में रीढ़ या jQuery.ajaxError से घटनाओं, का प्रयोग करें
  • आपके सर्वर की प्रतिक्रिया एक प्राधिकरण विफलता का संकेत देना चाहिए, शायद एक 401 स्थिति
  • अपने आस्थगित वादा/jqXHR वस्तु वापस जाने के लिए मत भूलना जब आप सिंक ओवरराइड, कि आ सकते हैं सुझाव लाइन
+0

धन्यवाद, अब मैं देखता हूं कि मैंने स्थगित होने का प्रयास कब किया था।आपके सुझावों के बारे में, आप शायद सही हैं - मैं रिलागिन को कम करने की कोशिश करूंगा, इससे भी बदतर है कि मेरे पास सर्वर प्रतिक्रियाओं पर कोई नियंत्रण नहीं है (सभी विरासतों में एक विरासत एसएसओ अवरोध है) – d4kris

+0

आप xhr ऑब्जेक्ट को वापस क्यों नहीं लौटते नया वादा करने के बजाए आपका नया सिंक() फ़ंक्शन? –

+0

क्योंकि सफलता और विफलता की शर्तें xhr द्वारा परिभाषित नहीं हैं – nikoshr

9

सभी सिंक त्रुटियों को मॉडल के error ईवेंट पर पास किया गया है, इसलिए आप इस घटना को सुन सकते हैं।

http://backbonejs.org/#Events-catalog से:

"त्रुटि" (मॉडल, XHR, विकल्प) - जब एक मॉडल के कॉल बचाने के सर्वर पर विफल रहता है।

त्रुटि कैप्चर करने के लिए विश्व स्तर पर आप उपयोग कर सकते हैं http://api.jquery.com/ajaxError/

+0

क्या वैश्विक स्तर पर सभी मॉडलों और संग्रहों को सुनना संभव है? यह त्रुटि कभी भी हो सकती है इसलिए मैं इसे वैश्विक रूप से संभालना चाहता हूं। वैसे भी, मुझे त्रुटि को पकड़ने और इसे संभालने की आवश्यकता है, न केवल इसे सुनें, इसलिए मुझे नहीं लगता कि यह मेरे परिदृश्य में काम करेगा। – d4kris

+0

मैंने अपने समाधान को संभावित समाधान के साथ अपडेट किया है। –

+0

क्या आप यहां jquery AJAX हैंडलर के साथ रीढ़ की हड्डी की घटनाओं को भ्रमित नहीं कर रहे हैं? AFAIK, AJAXError रीढ़ की हड्डी त्रुटि घटना से संबंधित नहीं है; यदि आप मैन्युअल रूप से एक त्रुटि ईवेंट ट्रिगर करते हैं, उदाहरण के लिए, आप AJAXError हैंडलर को नहीं फेंकेंगे, और कॉलबैक के लिए तर्क अलग-अलग होंगे – SpoonMeiser

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