J'ai une application avec un service qui encapsule mes appels d'API:
var ConcernService = {
...
get: function (items_url, objId) {
var defer = $q.defer();
$http({method: 'GET',
url: api_url + items_url + objId}).
success(function (data, status, headers, config) {
defer.resolve(data);
}).error(function (data, status, headers, config) {
console.log('ConcernService.get status',status);
defer.reject(status);
});
return defer.promise;
},
et j'utilise UI-Router pour la transition entre les états:
concernsApp
.config( function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/404/");
$stateProvider.state('project', {
url: '/project/:projectId/',
resolve: {
project: function ($stateParams, ConcernService) {
return ConcernService.get('projects/', $stateParams.projectId);
},
},
views: {
...
}
});
Je commence à utiliser le routeur AngularJS normal et j'ai du mal à comprendre comment implémenter des 404. Je peux voir la ConcernService
rejeter le statut console.log
comme rejeté, mais comment puis-je intercepter cela dans le routeur d'état?
La règle otherwise()
n'est invoquée que si aucun autre route ne correspond. Ce que vous voulez vraiment, c'est intercepter l'événement $stateChangeError
, qui est déclenché en cas de problème lors d'une transition d'état (par exemple, un échec de la résolution). Vous pouvez en savoir plus à ce sujet dans la documentation d'événement de changement d'état state .
La mise en œuvre la plus simple pour ce que vous essayez de faire serait quelque chose comme ceci:
$rootScope.$on('$stateChangeError', function(event) {
$state.go('404');
});
De plus, étant donné que $http
est lui-même construit sur des promesses (que resolve
résout), votre méthode ConcernService
peut être simplifiée à un seul niveau (je me rends compte que vous l'avez développé à des fins de débogage, mais vous pourriez tout aussi facilement l'enchaîner, juste pour information) :
var ConcernService = {
get: function (items_url, objId) {
return $http.get(api_url + items_url + objId);
}
}
Je diffère entre deux états 404:
Serveur:
Client:
Code pour Angular Etat du routeur UI:
$stateProvider
.state('404server', {
templateUrl: '/views/layouts/404.html'
})
.state('404client', {
url: '*path',
templateUrl: '/views/layouts/404.html'
});
Code dans l'intercepteur $httpProvider
:
if(response.status === 404) {
$injector.get('$state').go('404server');
}
Et pourquoi j’ai utilisé $injector
au lieu de $state
s’explique ici .
Vous pouvez également essayer quelque chose comme ceci et voir si cela fonctionne pour vous. Vous devrez peut-être vous adapter à vos besoins:
.state('otherwise', {
abstract: true,
templateUrl: 'views/404.html'
})
.state('otherwise.404', {
url: '*path',
templateUrl: 'views/404.html'
})
$ UrlRouterProvider fonctionne uniquement comme une surveillance de $ sur $ location et si l'URL réelle correspond à l'une des règles définies dans la fonction .config (), il sera redirigé vers la route spécifiée.
Voici ce que je recommande, définissez "/ 404 /" comme un état:
$stateProvider.state('404', {
url:'/404/',
views:{
...
}
});
Et à l'intérieur de la fonction rejeter () passer à l'état 404
if(status == '404'){
$state.transitionTo('404');
}
Vous devrez ajouter ui-router en tant que dépendance du module de projet et utiliser le fournisseur $ state de votre contrôleur pour pouvoir utiliser $ state.transitionTo ().
Voici quelques informations: https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statetransitiontoto-toparams--options
J'ai réussi à gérer 404 sans utiliser $urlRoutProvider
puisque je n'utilise que des états en testant $state.transistion
:
angular.module("app", []).run(["$state", "$rootScope", function($state, $rootScope) => {
$rootScope.$on("$locationChangeSuccess", function() {
if (!$state.transition) {
$state.go("404");
}
});
}]);