我有一个带有Angularjs和Coldfusion的应用程序。我有一个表单,其中包含一些用于填充下拉列表的http查询。当会话服务器关闭时,我从服务器检索状态,显示一个对话框(感谢ngDialog(并重新加载页面。(状态 0 由服务器发送,因为服务器在进入应用程序主页之前尝试重新加载外部身份验证系统 - 不在本主题的讨论范围内(。
这是我的代码:
app.controller('ctrlAddContacts', function ($scope, $route, ContactService, ngDialog, $timeout){
ContactService.getCountry().success(function(countries){
$scope.countries = countries;
});
ContactService.loadCategory('undefined',0).success(function(categories, status, header, config){
$scope.categories = categories;
console.log("status:" + status);
})
.error(function (data, status, header, config) {
console.log("sessionExpired: " + sessionExpired);
console.log("ERROR ");
console.log("data: " + data);
console.log("status:" + status);
console.log("header: " + header);
console.log("config: " + config);
if (status==0) {
alert("Your session expired - The page needs to be reloaded.nPlease note that data enter in the form will be lost");
// NGDIALOG BOX
var dialog = ngDialog.open({
template: '<p>Your session expired - The page needs to be reloaded.<br />Please note that data enter in the form will be lost</p>',
plain: true,
closeByDocument: false,
closeByEscape: false
});
setTimeout(function () {
dialog.close();
window.location = "http://myapp/index.cfm?#/add-contacts";
}, 4000);
}
}).finally(function() {
console.log("finally finished repos");
});
});
它正在工作,但我必须为每个 ajax HTTP 请求执行此操作。
在这里,我必须做同样的事情:
ContactService.getCountry().success(function(countries){
$scope.countries = countries;
});
因此,我想简化代码以避免重复该行,您能否告诉我是否可以这样做以及如何(例如指令或工厂(?
谢谢
service
来处理控制器中的所有$http
,在此示例中,我尝试通过使用$q
传递来自服务的响应来连接controller
和service
结果是对话框将在服务中处理,您也可以在控制器中获取响应。
var app = angular.module("app", []);
app.controller("ctrl", function ($scope, service) {
service.get('getCountry').then(function (data) {
console.log(data);
})
})
app.service("service", function ($http, $q, ContactService, ngDialog, $timeout) {
this.get = function (api) {
var deferred = $q.defer();
//we used angular 1.6 => use then instead success
ContactService[api]().then(function (response) {
deferred.resolve(response.data);
}, function (error) {
if (error.status == 0) {
alert("Your session expired - The page needs to be reloaded.nPlease note that data enter in the form will be lost");
var dialog = ngDialog.open({
template: '<p>Your session expired - The page needs to be reloaded.<br />Please note that data enter in the form will be lost</p>',
plain: true,
closeByDocument: false,
closeByEscape: false
});
$timeout(function () {
dialog.close();
window.location = "http://myapp/index.cfm?#/add-contacts";
}, 4000);
} else {
alert("status is " + error.status);
}
})
return deferred.promise;
}
})
你可以为此使用拦截器,
.factory('myInterceptor', ['$q', '$location', '$injector', function ($q, $location, $injector) {
return {
response: function (response) {
if (response.status === 0) {
console.log('http 0 response')
}
return response || $q.when(response);
},
responseError: function (rejection) {
return $q.reject(rejection);
}
}
}])
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push('myInterceptor');
}]);
此外,拦截器还可用于全局错误处理、身份验证或任何类型的请求同步或异步预处理或响应的后处理。