我试图在 $routeProvider
中使用 resolve
仅在 $http
请求完成时显示新路由 . 如果请求成功,则解析$ http.post()产生的承诺并呈现视图 . 但是如果请求失败(例如,超时或内部错误),则永远不会解析承诺,并且永远不会呈现视图 . 如何使用 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并解决它,即使请求失败,但我想知道是否有更简单的解决方案 .
感谢阅读,并希望,帮助:)
3 回答
我认为从
resolve
执行此操作的唯一方法是手动解决Warranty.sendRequest
返回的承诺并将其重新包装在新的承诺中:在
WarrantyResultCtrl
中,您可以检查是否发生了错误并生成重定向 .EDIT :更清洁的解决方案:
(plunker演示)
我发现如果
Promise
是rejected
,控制器根本不会被触发,并且您的视图永远不会被渲染 - 与您相同 .我还发现,如果你在
$routeProvider
的resolve
中使用.then()
处理Promise
,.then()
将返回一个新的Promise
,即resolved
并且你的控制器终究会被触发,尽管没有你期望的数据 .例如:
现在在您的控制器中,您需要检查
response
是否为undefined
. 如果它是undefined
那么您将知道对Warranty.sendRequest()
的调用失败,您可以采取相应的行动 .对于它的 Value ,我没有走这条路 . 相反,我将
$location
服务注入resolve
处理程序,并在$http
调用被拒绝时重定向到错误页面 .UPDATE 刚刚注意到在你的控制器中注入
Warranty
服务时应该注入resolve
中定义的response
. 这将阻止您的视图呈现,直到从Warranty.sendRequest()
返回的Promise得到解决 .深入搜索后,我无法找到解决此问题的方法 .
我决定在我的路由定义中删除解析参数,并在WarrantyCtrl中使用以下代码片段 .
不是很聪明,但是工作有意......如果有人仍然有原始问题的解决方案,我会很高兴看到它!