2013-06-07 10 views
13

हल करें $routeProvider में $routeProvider में $http अनुरोध समाप्त होने पर केवल नए रूट को प्रदर्शित करने का प्रयास कर रहा हूं। अगर अनुरोध सफल होता है, तो $ http.post() से उत्पन्न वादा हल हो जाता है और दृश्य प्रस्तुत किया जाता है। लेकिन अगर अनुरोध विफल रहता है (उदाहरण के लिए टाइमआउट या आंतरिक त्रुटि), वादा कभी हल नहीं होता है और दृश्य कभी प्रस्तुत नहीं किया जाता है। resolve का उपयोग कर अनुरोध विफलता से मैं कैसे निपट सकता हूं?

कोड के सबसे महत्वपूर्ण भागों bellow है:

app.js

$routeProvider.when('/warrantyResult', { 
    templateUrl : 'partials/warranty-result.html', 
    controller : 'WarrantyResultCtrl', 
    resolve : { 
     response : [ 'Warranty', function(Warranty) { 
      return Warranty.sendRequest(); 
     } ] 
    } 
}); 

controllers.js

angular.module('adocDemo.controllers', []).controller('HomeCtrl', [ '$scope', function($scope) { 

} ]).controller('WarrantyCtrl', [ '$scope', '$http', '$location', 'Warranty', function($scope, $http, $location, Warranty) { 
    $scope.submitWarranty = function() { 
     $scope.loading = true; 
     Warranty.setRequestData($scope.data); 
     $location.path('/warrantyResult'); 
    }; 
} ]).controller('WarrantyResultCtrl', [ '$scope', 'Warranty', function($scope, Warranty) { 

    $scope.request = Warranty.getRequestData(); 
    $scope.response = Warranty.getResponseData(); 
} ]); 

services.js

angular.module('adocDemo.services', []).factory('Warranty', [ '$http', '$timeout', function($http, $timeout) { 
    /** 
    * This service is used to query the Warranty Webmethod. The sendRequest 
    * method is automaticcaly called when the user is redirected to 
    * /warrantyResult route. 
    */ 
    var isDataSet = false; 
    var requestData = undefined; 
    var responseData = undefined; 
    return { 
     setRequestData : function(data) { 
      //Setting the data 
      isDataSet = true; 
     }, 
     getRequestData : function() { 
      return requestData; 
     }, 
     sendRequest : function(data) { 
      if(isDataSet) { 
       var request = $http.post('url/to/webservice', requestData); 
       request.success(function(data) { 
        responseData = data; 
       }); 
       return request; 
      } 
     }, 
     getResponseData : function() { 
      return responseData; 
     } 
    }; 
} ]); 

मुझे पता है मैं एक वादा का उपयोग कर सकता था $ http कॉल के दौर में और अनुरोध विफल होने पर भी इसे हल करें, लेकिन मुझे आश्चर्य है कि कोई आसान समाधान है या नहीं।

पढ़ने और हमें उम्मीद है कि :)

+0

निर्भर करता है कि संकल्प विफल होने पर आप अपने ऐप को कैसे व्यवहार करना चाहते हैं? – Stewie

+0

संकल्प विफल होने पर उपयोगकर्ता को एक अलग मार्ग (/ requestError?) पर रीडायरेक्ट करना सबसे अच्छा व्यवहार होगा। या/वारंटी को प्रस्तुत किया जा सकता है और इस मार्ग का नियंत्रक यह जांचने के लिए प्रभारी होगा कि अनुरोध सफल था या नहीं। – pdegand59

उत्तर

0

की मदद करने गहरी खोज के बाद के लिए धन्यवाद, मैं इस समस्या के लिए एक समाधान नहीं मिल सका।

मैंने अपनी रूट परिभाषा में संकल्प स्टेटमेंट को छोड़ने का निर्णय लिया और मैं वारंटी कोड में कोड के निम्न स्निपेट का उपयोग करता हूं।

$scope.submitWarranty = function() { 
    $scope.formatUserData(); 
    if ($scope.verifyUserData()) { 
     $scope.loading = true; 
     Warranty.setRequestData($scope.data); 
     Warranty.sendRequest().success(function() { 
      $location.path('/warrantyResult'); 
     }).error(function() { 
      $location.path('/webserviceError'); 
     }); 
    } 
}; 

बहुत चालाक नहीं है, लेकिन के रूप में काम करता है intented ... किसी भी मूल समस्या के लिए समाधान है, तो मैं बहुत इसे पढ़ने के लिए खुश होगा!

+0

केवल '$ location.path ('/ webserviceError') के बारे में क्या है और इसे' $ http' कॉल के त्रुटि हैंडलर में करें। ताकि आप मार्ग हल कर सकें और आपको अस्वीकार किए गए वादे के बारे में सोचने की आवश्यकता नहीं है क्योंकि इसे सेवा –

8

मुझे लगता है कि resolve से यह करने के लिए एक ही रास्ता मैन्युअल रूप से वादा Warranty.sendRequest द्वारा लौटाए को हल करने और एक नया वादा में यह हर दूसरे पट्टी बदल करने के लिए है:

resolve : { 
    response : [ 'Warranty' '$q', function(Warranty, $q) { 
    var dfd = $q.defer(); 

    Warranty.sendRequest().then(function(result) { 
     dfd.resolve({ success: true, result : result }); 
    }, function(error) { 
     dfd.resolve({ success : false, reason : error }); 
    }); 

    return dfd.promise; 

    } ] 
} 

WarrantyResultCtrl में, आप अगर एक त्रुटि हो गई जाँच करें और उत्पन्न कर सकता है एक पुनर्निर्देशन।

संपादित: अधिक स्वच्छ समाधान:

// WarrantyCtrl 
$scope.$on('$routeChangeError', function() { 
    // handle the error 
}); 
$scope.submitWarranty = function() { 
    $scope.loading = true; 
    Warranty.setRequestData($scope.data); 
    $location.path('/warrantyResult'); 
}; 

(plunker demo)

+0

में संभाला जाएगा आपका प्लंकर काम नहीं कर रहा है। लेकिन वैसे भी आपके जवाब के लिए thx! मैं आपके समाधान पर एक शॉट देने जा रहा हूँ। – pdegand59

+0

@ pdegand59 whoops, क्षमा करें! मैंने स्पष्ट रूप से कल थोड़ा सा साफ़ किया :( – robertklep

3

क्या मैं ने पाया है कि नियंत्रक बिल्कुल अगर Promiserejected है निकाल दिया नहीं है, और आपके विचार है कभी प्रस्तुत नहीं किया जाता है - आपके जैसा ही।

क्या मैं यह भी पता चला है कि अगर आप अपने $routeProvider के resolve में एक .then() साथ Promise संभाल, .then() एक नया Promise कि है resolved वापस आ जाएगी और यद्यपि डेटा के बिना आप उम्मीद कर रहे हैं अपने नियंत्रक, सब के बाद निकाल दिया जाता है ।

उदाहरण के लिए:

$routeProvider.when('/warrantyResult', { 
    templateUrl : 'partials/warranty-result.html', 
    controller : 'WarrantyResultCtrl', 
    resolve : { 
     response : [ 'Warranty', function(Warranty) { 
      return Warranty.sendRequest() 
       .then(null, function(errorData) { 
        // Log an error here? 
        // Or do something with the error data? 
       }); 
     }] 
    } 
}); 

अब आप अपने नियंत्रक में आप चाहे responseundefined है जाँच करना चाहते हैं जाएगा। यदि यह undefined है तो आपको पता चलेगा कि Warranty.sendRequest() पर कॉल विफल रहा है, और आप तदनुसार कार्य कर सकते हैं।

इसके लायक होने के लिए, मैं इस मार्ग पर नहीं गया था। इसके बजाय, मैंने $location सेवा को resolve हैंडलर में इंजेक्शन दिया और $http कॉल अस्वीकार कर दिया गया है तो एक त्रुटि पृष्ठ पर रीडायरेक्ट किया गया।

अद्यतन बस देखा है कि आपके नियंत्रक में आप Warranty सेवा इंजेक्शन कर रहे हैं जब आप के बजाय response है कि आप अपने resolve में परिभाषित इंजेक्शन लगाने की जानी चाहिए। इससे आपके विचार को प्रतिपादन से रोका जाएगा जब तक कि Warranty.sendRequest() से वादा वापस नहीं किया जाता है।

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