我尝试在$routeProvider中使用resolve,以便仅在$http请求完成时才显示新路由。如果请求成功,则解析由$http.post()产生的promise并呈现视图。但是如果请求失败(例如超时或内部错误),promise永远不会被解决,视图也永远不会被呈现。如何使用resolve处理请求失败?
代码中最重要的部分如下:
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调用周围使用promise,即使请求失败也可以解决它,但我想知道是否有更简单的解决方案。
感谢您的阅读,希望对您有所帮助:)
发布于 2013-12-14 04:35:43
我发现,如果Promise为rejected,则控制器根本不会触发,并且永远不会呈现您的视图--与您一样。
我还发现,如果您在$routeProvider的resolve中使用.then()处理$routeProvider,那么.then()将返回一个新的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?
});
}]
}
});现在,在您的控制器中,您需要检查response是否为undefined。如果它是undefined,那么您就会知道对Warranty.sendRequest()的调用失败了,您可以相应地采取相应的操作。
不管怎么说,我没有走这条路。相反,我将$location服务注入到resolve处理程序中,并在$http调用被拒绝时重定向到错误页面。
UPDATE刚刚注意到,在您的控制器中,您正在注入Warranty服务,而实际上您应该注入您在resolve中定义的response。这将阻止您的视图呈现,直到解析从Warranty.sendRequest()返回的Promise。
发布于 2013-06-10 21:44:03
经过深入的搜索,我找不到解决这个问题的方法。
我决定在我的路由定义中删除resolve语句,并在WarrantyCtrl中使用以下代码片段。
$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');
});
}
};不是很聪明,但工作就像预期的那样。如果有人仍然有原始问题的解决方案,我将非常高兴地阅读它!
https://stackoverflow.com/questions/16987341
复制相似问题