web-dev-qa-db-fra.com

AngularJS UI router traitant 404s

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?

13
Darwin Tech

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);
  }
}
22
Nate Abele

Je diffère entre deux états 404:

Serveur:

  • afficher la page 404 en fonction de la réponse du serveur Code HTTP 404
  • important de définir no URL, de sorte que l'utilisateur reste sur l'URL où l'erreur s'est produite

Client:

  • L'URL n'est pas trouvée par le routeur UI angulaire (aucune des URL définies).

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 .

7
Betty St

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'
})
3
ucsarge

$ 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

2
Alejandro Figueroa

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");
        }
    });
}]);
1
Claudio Mezzasalma