La demande $ http avant l'initialisation de l'application AngularJS?

Afin de déterminer si la session d'un utilisateur est authentifiée, je dois faire une demande $ http au serveur avant que le premier itinéraire ne soit chargé. Avant chaque chargement, un service d'authentification vérifie l'état de l'utilisateur et le niveau d'accès requis par l'itinéraire, et si l'utilisateur n'est pas authentifié pour cette route, il redirige vers une page de connexion. Toutefois, lorsque l'application est chargée pour la première fois, elle n'a aucune connaissance de l'utilisateur. Par conséquent, même si elles ont une session authentifiée, elles redirigent toujours vers la page de connexion. Donc, pour résoudre ce problème, j'essaie de faire une requête au serveur pour le statut des utilisateurs dans le cadre de l'initialisation de l'application. La question est que, évidemment, les appels de $ $ sont asynchrones, alors comment arrêterais-je l'application jusqu'à ce que la demande soit terminée?

Je suis très nouveau dans le développement angulaire et frontalier en général, donc mon problème peut-être un malentendu de javascript plutôt que d'Angular.

Vous pourriez accomplir cela en utilisant la resolve dans votre fournisseur de routage.

Cela vous permet d'attendre que certaines promesses soient résolues avant que le contrôleur ne soit initié.

Quote from the docs:

Resolve – {Object. =} – Une carte facultative des dépendances qui doivent être injectées dans le contrôleur. Si l'une de ces dépendances est une promesse, le routeur les attendra tous pour être résolus ou un autre sera rejeté avant que le contrôleur ne soit mis en place. Si toutes les promesses sont résolues avec succès, les valeurs des promesses résolues sont injectées et l'événement $ routeChangeSuccess est déclenché.

Exemple simple

  app.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: { myVar: function($q,$http){ var deffered = $q.defer(); // make your http request here and resolve its promise $http.get('http://example.com/foobar') .then(function(result){ deffered.resolve(result); }) return deffered.promise; } }}). otherwise({redirectTo: '/'}); }]); 

MyVar sera alors injecté dans votre contrôleur, contenant les données de promesses.

Éviter le paramètre DI supplémentaire

Vous pouvez également éviter le paramètre DI supplémentaire en renvoyant un service que vous allez injecter de toute façon:

 app.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: { myService: function($q,$http,myService){ var deffered = $q.defer(); /* make your http request here * then, resolve the deffered's promise with your service. */ deffered.resolve(myService), return deffered.promise; } }}). otherwise({redirectTo: '/'}); }]); 

De toute évidence, vous devrez stocker le résultat de votre demande n'importe où dans un service partagé lorsque vous faites des choses comme ça.


Jetez un oeil à Angular Docs / routeProvider

J'ai appris la plupart de ces choses de ce mec à egghead.io

Encapsulez toutes vos ressources avec une sessionCreator et sessionCreator -vous une promesse. Après avoir resolve ensuite à votre contrôleur afin que vous puissiez le garder libre du code de promise spécifique.

 app.factory('sessionCreator', ['$http', '$q', 'urlApi', function ($http, $q, urlApi) { var deferred = $q.defer(); $http.get(urlApi + '/startPoint').success(function(data) { // Do what you have to do for initialization. deferred.resolve(); }); return deferred.promise; } ]); app.factory('Product', ['$resource', 'urlApi', 'sessionCreator', function($resource, urlApi, sessionCreator) { // encapsulate all yours services with `sessionCreator` return sessionCreator.then(function() { return $resource(urlApi + '/products', {}, { query: {method:'GET', params:{}, isArray: true} }); }); } ]); app.config(['$routeProvider', function ($routeProvider) { var access = routingConfig.accessLevels; $routeProvider .when('/product', { templateUrl: 'views/products.html', controller: 'ProductCtrl', // resolve then in router configuration so you don't have to call `then()` inside your controllers resolve: { Product: ['Product', function(Product) { return Product; }] } }) .otherwise({ redirectTo: '/' }); }]);