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?
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 .
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(...);
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);
});
}
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;
}])
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.
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.)
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;
}
};
}
);
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.