AngularJS -拒绝了使用$routeProvider:resolve的$http承诺
AngularJS - rejected $http promise with $routeProvider:resolve
我试图在$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调用周围使用一个承诺并解决它,即使请求失败,但我想知道是否有一个更简单的解决方案。
谢谢你的阅读,希望能有所帮助:)
我认为从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
中,您可以检查是否发生错误并生成重定向。
EDIT:更干净的解决方案:
// WarrantyCtrl
$scope.$on('$routeChangeError', function() {
// handle the error
});
$scope.submitWarranty = function() {
$scope.loading = true;
Warranty.setRequestData($scope.data);
$location.path('/warrantyResult');
};
<年代>(恰好演示) 年代>
我发现的是,如果Promise
是rejected
,控制器根本不会被触发,并且您的视图永远不会呈现—与您相同。
我还发现,如果您在$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?
});
}]
}
});
现在在控制器中,您将需要检查response
是否为undefined
。如果是undefined
,那么您将知道对Warranty.sendRequest()
的调用失败,并且您可以相应地采取行动。
无论如何,我没有走这条路。相反,我将$location
服务注入到resolve
处理程序中,并在$http
调用被拒绝时重定向到错误页面。
只是注意到,在您的控制器中,当您应该注入您在resolve
中定义的response
时,您正在注入Warranty
服务。这将阻止你的视图渲染,直到从Warranty.sendRequest()
返回的Promise被解析。
经过深入研究,我找不到解决这个问题的方法。
我决定在路由定义中删除resolve语句,并在warantyctrl中使用以下代码片段:
$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');
});
}
};
不是很聪明,但效果很好…如果有人还有解决原来问题的方法,我将非常乐意阅读!
- Meteor如何接收HTTP请求
- 在我的情况下,如何进行http请求
- //而不是在src=“”上使用http://"属性
- 我无法使用angularJs($http)访问服务器
- AJAX简单错误.XMLHttpRequest无法加载http://localhost/mpl/getPage.php.
- 如何将PHP get查询转换为Meteor's HTTP.get()
- 角度异步http自动完成
- 什么's本地node.js服务器和python简单http服务器之间的区别
- 角度http服务器页面刷新404s
- http.listen()在运行时接受终端命令
- IIS动态HTTP响应标头
- spring和angularJS(我得到了类似HTTP状态404的错误)
- 存储$http如何从$http函数(Angularjs)外部获取可访问变量中的响应
- Typescript angularjs$http获取响应类型(避免使用<any>)
- 如何从HTTP上下文对象中获取Post数据
- 使用插件收听Firefox标签的http请求
- "访问控制允许起源”;通过javascript从http页面调用同一网站的httpsurl时出现问题
- AngularJS -拒绝了使用$routeProvider:resolve的$http承诺
- 在angularjs的ui.router's resolve中做$http get请求是可以的吗?
- Angular JS $http.success() vs $q.resolve()?