web-dev-qa-db-fra.com

Mettre en cache une réponse de service HTTP 'Get' dans AngularJS?

Je souhaite pouvoir créer un service AngularJS personnalisé qui crée une demande HTTP "Obtenir" lorsque son objet de données est vide et renseigne l'objet de données en cas de succès.

Lors du prochain appel à ce service, je souhaiterais éviter la surcharge liée à la nouvelle requête HTTP et renvoyer à la place l'objet de données mis en cache.

Est-ce possible?

210
Gavriguy

L'angle $ http a un cache intégré . Selon les docs:

cache - {boolean | Object} - Valeur booléenne ou objet créé avec $ cacheFactory pour activer ou désactiver la mise en cache de la réponse HTTP. Voir $ http Caching pour plus d'informations .

Valeur booléenne

Vous pouvez donc définir cache sur true dans ses options:

$http.get(url, { cache: true}).success(...);

ou, si vous préférez le type d’appel config:

$http({ cache: true, url: url, method: 'GET'}).success(...);

Objet cache

Vous pouvez également utiliser une fabrique de cache:

var cache = $cacheFactory('myCache');

$http.get(url, { cache: cache })

Vous pouvez l'implémenter vous-même en utilisant $ cacheFactory (particulièrement en utilisant $ resource):

var cache = $cacheFactory('myCache');

var data = cache.get(someKey);

if (!data) {
   $http.get(url).success(function(result) {
      data = result;
      cache.put(someKey, data);
   });
}
312
asgoth

Je pense qu'il y a un moyen encore plus facile maintenant. Cela active la mise en cache de base pour toutes les demandes $ http (dont $ ressource hérite):

 var app = angular.module('myApp',[])
      .config(['$httpProvider', function ($httpProvider) {
            // enable http caching
           $httpProvider.defaults.cache = true;
      }])
48
gspatel

Un moyen plus simple de le faire dans la version stable actuelle (1.0.6) nécessite beaucoup moins de code.

Après avoir configuré votre module, ajoutez une usine:

var app = angular.module('myApp', []);
// Configure routes and controllers and views associated with them.
app.config(function ($routeProvider) {
    // route setups
});
app.factory('MyCache', function ($cacheFactory) {
    return $cacheFactory('myCache');
});

Maintenant, vous pouvez le transmettre à votre contrôleur:

app.controller('MyController', function ($scope, $http, MyCache) {
    $http.get('fileInThisCase.json', { cache: MyCache }).success(function (data) {
        // stuff with results
    });
});

L'inconvénient est que les noms de clé sont également configurés automatiquement, ce qui peut compliquer leur nettoyage. J'espère qu'ils ajouteront quelque chose pour obtenir les noms de clés.

12
James Skemp

Consultez la bibliothèque angular-cache si vous aimez la mise en cache intégrée de $ http mais que vous souhaitez davantage de contrôle. Vous pouvez l'utiliser pour augmenter de manière transparente le cache $ http avec des purges périodiques et la durée de vie, ainsi que l'option de maintien du cache sur localStorage afin qu'il soit disponible pour toutes les sessions.

FWIW, il fournit également des outils et des modèles permettant de transformer votre cache en un type de magasin de données plus dynamique avec lequel vous pouvez interagir en tant que POJO, au lieu des chaînes JSON par défaut. Je ne peux pas encore commenter l'utilité de cette option.

(Ensuite, la bibliothèque associée angular-data est en quelque sorte une solution de remplacement pour $ resource et/ou Restangular, et dépend de angular-cache.)

7
XML

Comme les usines AngularJS sont singletons , vous pouvez simplement stocker le résultat de la requête http et le récupérer la prochaine fois que votre service est injecté dans quelque chose.

angular.module('myApp', ['ngResource']).factory('myService',
  function($resource) {
    var cache = false;
    return {
      query: function() {
        if(!cache) {
          cache = $resource('http://example.com/api').query();
        }
        return cache;
      }
    };
  }
);
5
Rimian
angularBlogServices.factory('BlogPost', ['$resource',
    function($resource) {
        return $resource("./Post/:id", {}, {
            get:    {method: 'GET',    cache: true,  isArray: false},
            save:   {method: 'POST',   cache: false, isArray: false},
            update: {method: 'PUT',    cache: false, isArray: false},
            delete: {method: 'DELETE', cache: false, isArray: false}
        });
    }]);

définir le cache pour être vrai.

2
Howardyan