web-dev-qa-db-fra.com

AngularJS: Comment puis-je mettre en cache les données JSON renvoyées par l'appel $ http?

Comment puis-je mettre en cache les données JSON renvoyées par l'appel $ http. J'utilise le style suivant d'appel $ http:

$http({
        url: 'SomeWebMethodUrl',
        method: "POST",
        data: "{'query':'somevalue'}",
        headers: { 'Content-Type': 'application/json' }
    }).success(function (data, status, headers, config) {
        //something in success
    }).error(function (data, status, headers, config) {
        //something in error
    });

J'ai consulté le didacticiel suivant: https://coderwall.com/p/40axlq sur la mise en cache de la réponse du serveur à partir de l'appel $ http. Mais il explique le style $ http.get () et mettra en cache les données et ne fera pas de deuxième requête $ http si l'URL absolue est la même.

Puis-je utiliser la mise en cache avec mon style d'appel $ http lorsque ma propriété 'data' est identique pour les mêmes appels de méthodes Web à l'avenir? J'utilise le service Web ASP.net ASMX pour mes WebMethods.

17
Pawan Pillai

Le cache angular.js est conçu pour les appels HTTP GET uniquement. Cela est cohérent avec l'intention du protocole HTTP, car les serveurs HTTP ne cherchent généralement pas au-delà des en-têtes URL, Méthode HTTP et Cache-Control pour déterminer s'ils peuvent répondre à une demande avec un contenu mis en cache. En conséquence, les auteurs de angular n’ont pas étendu la fonctionnalité de mise en cache à d’autres méthodes HTTP.

Une autre façon de voir les choses est que le service $ cache angulaire n’est en réalité qu’un simple magasin de valeurs de clé, l’URL de la requête faisant office de clé et la réponse à la requête HTTP GET la valeur stockée localement au lieu de la serveur.

Lorsque vous y réfléchissez, vous comprenez pourquoi il est plus difficile de mettre en cache la réponse à une demande POST. Le contenu renvoyé par la demande POST dépend non seulement de l'URL, mais également du contenu POSTé. Pour mettre en cache ce résultat dans un magasin de valeurs de clé, vous avez besoin d'un mécanisme permettant de créer une clé unique qui identifie à la fois l'URL et les données transmises.

Si vos données sont assez simples, ma suggestion est d'écrire votre propre cache qui est vérifié avant d'utiliser le service $ http angulaire. Sans en savoir plus sur votre méthode de données, je ne peux pas vous donner un exemple complet, mais vous pourriez faire quelque chose comme ça:

angular.module('myModule').service('myDataService', function($cacheFactory, $http) {

  var cache = $cacheFactory('dataCache');

  function success(data, status, headers, config) {
    // some success thing
  }

  function error(data, stats, headers, config) {
    // some error thing
  }

  this.getSomeData = function(url, query) {
    var cacheId = url + '*' + query;
    var cachedData = cache.get(cacheId);
    // Return the data if we already have it
    if (cachedData) {
      success(cachedData);
      return;
    }

    // Got get it since it's not in the cache
    $http({url: url,
           method: 'POST',
           data: {query: query},
           headers: { 'Content-Type': 'application/json' }  // Probably not necessary, $http I think does this 
         }).success(function(data, status, headers, config) {
              // Put this in our cache using our 'unique' id for future use
              cache.put(cacheId, data);
              success(data, status, headers, configs);
         }).error(error);    

  };

});

Vous pouvez alors remplacer ce service d'encapsulation par lequel vous utilisez actuellement le service brut $ http.

Le but est d’implémenter votre propre cache qui comprend l’URL + les données comme une clé avant d’appeler le service $ http.

31
Geoff Genz

L'utilisation de la demande POST utilisée pour ajouter de nouveaux enregistrements dans le magasin de données, PUT et DELETE modifie l'état du magasin de données. Et cela n'a aucun sens d'en encaisser un.

Seul GET récupère les données sans modifier le magasin de données. Et cela a du sens d'encaisser sa réponse.

0
Yousef