问题
I use Restangular
in my angularjs App & use setErrorInterceptor
to handle response error in one place. I want to redirect user to login page if an error occured. I know that the only providers
& constants
are injectable in configuration phase.
var app = angular.module('ourstandApp', ['ngRoute', 'restangular', 'ui.bootstrap', 'ngCookies', 'angularFileUpload']);
// Global configuration
app.config(function (RestangularProvider, baseRequestConfig, $routeProvider, urlsProvider) {
var getBaseRequestUrl = function () {
return baseRequestConfig.protocol + "://" + baseRequestConfig.hostName + ":" + baseRequestConfig.portNumber + baseRequestConfig.resourcePath;
}
var initializeRoute = function () {
$routeProvider.when('/', {
controller: LoginController,
templateUrl: 'views/login.html'
}).
otherwise({
redirectTo: '/'
});
}
initializeRoute();
RestangularProvider.setBaseUrl(getBaseRequestUrl());
RestangularProvider.setErrorInterceptor(function (resp) {
goToLogin(); // i want to change url to login page
return false;
});
});
回答1:
the correct way for handling this problem is configuring restangular in run
method of angularjs
app.run(Restangular , $location){
Restangular.setErrorInterceptor(function (resp) {
$location.path('/login');
return false;
});
}
回答2:
Inject $injector
to the config block and invite $location
when needed:
RestangularProvider.setErrorInterceptor(function (resp) {
var $location = $injector.get('$location');
$location.path('/login');
return false;
});
Also check my other answers:
- inject $route into a http interceptor
- Is there a way to request $http for an interceptor?
回答3:
The idea here is to be more specific about how resources are requested. In this excerpt from a project i am using the resolve
option of routeProvider.when
to look up a resource based on path input and injecting the result as ArticleRequest
before resolving the route.
If the api calls the route fails and the $routeChangeError
event is fired
App.config(['$routeProvider', '$locationProvider', 'TEMPLATE_PATH',
function ($routeProvider, $locationProvider, TEMPLATE_PATH) {
$routeProvider.
when('/', {
templateUrl: TEMPLATE_PATH + 'views/Home.html',
controller: 'HomeCtrl',
caseInsensitiveMatch: true
}).
when('/:slug/:nocache?', {
templateUrl: TEMPLATE_PATH + 'views/Article.html',
controller: 'ArticleCtrl',
caseInsensitiveMatch: true,
resolve: {
ArticleRequest: ['$http', '$route', function ($http, $route) {
return $http.post('/api/article/GetArticleBySlug',
{
slug: $route.current.params.slug,
nocache: !!$route.current.params.nocache && $route.current.params.nocache == 'preview'
});
}]
}
}).
otherwise({
redirectTo: '/'
});
// configure html5 to get links working on jsfiddle
$locationProvider.html5Mode(true);
}]);
Here is a very simple implementation of the $routeChangeError
handler
App.run(['$rootScope', '$location', function($rootScope, $location) {
$rootScope.$on('$routeChangeError', function (e, current, previous, rejection) {
console.log("ROUTE ERROR:", current, previous, rejection);
// you might redirect here based on some logic
$location.path('[YOUR PATH]');
});
}]);
and here is the controller
ViewControllers.controller('ArticleCtrl',
['$scope', '$http', '$routeParams', 'ArticleRequest',
function ($scope, $http, $routeParams, ArticleRequest) {
console.log(ArticleRequest);
}]);
Is something like this usefull in you case with Restangular?
回答4:
If I understand you correctly you want to redirect the user to a login page based on a status code returned to you by the server? Like a 404 or 403?
If that's the case this is how I handle redirects on a 404 and 403 using setErrorInterceptor
in one of my apps. This may not be the best way to do this, but It's been working just fine so far for me.
app.config(['RestangularProvider', function (RestangularProvider) {
RestangularProvider.setErrorInterceptor(function (response) {
// Redirect the user to the login page if they are not logged in.
if (response.status == '403' && response.data.detail == 'Authentication credentials were not provided.') {
var next = window.location.pathname + window.location.hash;
window.location.href = '/accounts/login/?next=' + next;
}
// Redirect the user on a 404.
if (response.status == '404') {
// Redirect to a 404 page.
window.location.href = '/#/';
}
return response;
});
}]);
来源:https://stackoverflow.com/questions/21445886/angularjs-change-url-in-module-config