angularjs: как добавить кеширование в ресурсный объект?

Добавить кеширование внутри http довольно просто. (передавая кеш = true)

http://docs.angularjs.org/api/ng.$http имеет опцию кэширования.

Как добавить подобную функциональность в $ resource в angularjs?

 Mark Rajcok02 сент. 2012 г., 04:40
 DerWaldschrat03 нояб. 2012 г., 13:14
Что ж, это не решает проблему, "внедрите ее самостоятельно" это не то, что он и я ищем
 Andrew Joslin05 нояб. 2012 г., 15:20
Единственный ответ прямо сейчас - «внедри его сам» до следующей версии угловой. Вы можете использовать эту реализацию, которая находится в PR:github.com/angular/angular.js/pull/1045

Ответы на вопрос(8)

Это, кажется, не упоминается здесь, но вы также можете перезаписать методы по умолчанию.

app.factory("List", ["$resource", function($resource) {
    return $resource("./lists/:path/:action.json", {}, {
        get: {
            method: "GET",
            cache: true
        }
    });
}]);
 27 нояб. 2014 г., 03:25
Проблема сcache: true является то, что он только кэширует GET-запросы. Если вы хотите кэшировать HEAD-запросы, вам не повезло.

Как утверждают документы,$ ресурсов имеет встроенную поддержку$ CacheFactory, Вы можете передать его черезcache свойство каждого действия:

cache{boolean|Cache} – If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching.

Пример использования:

app.factory('Todos', function($resource, $cacheFactory) {
    var todosCache = $cacheFactory('Todos');
    return $resource(apiBaseUrl + '/todos/:id', {id: '@id'}, {
        'get': { method:'GET', cache: todosCache},
        'query': { method:'GET', cache: todosCache, isArray:true }
    });
});
 08 февр. 2015 г., 21:24
Вы должны передать экземпляр Cache (созданный с $ cacheFactory), а не сам $ cacheFactory.
 09 февр. 2015 г., 23:14
Спасибо, я соответственно обновил свой ответ.

Реализовать свой собственный кеш в AngularJs довольно просто. Просто используйте$ CacheFactory:

app.factory('myService', function($resource, $cacheFactory) {
   var cache = $cacheFactory('myService');
   var User = $resource('/user/:userId', {userId:'@id'});

   return {
      getResource: function(userId) {
         var user = cache.get(userId);
         if (!user) {
            user = User.get({userId:userId});
            cache.put(userId, user);   
         }
         return user;
      }
   };
});
 18 февр. 2014 г., 02:31
На самом деле, $ resource теперь имеет встроенную поддержку кеша. Не нужно продолжать делать это вручную.

Я только что наткнулся на этот действительно хорошо продуманный модуль angular-cached-resource, который сделает эту работу за вас.https://github.com/goodeggs/angular-cached-resource

Это капля замены $ resource, с добавленной функциональностью управления кешем с использованием localStorage. Если ваш браузер не поддерживает локальное хранилище, вы не получите никакой выгоды от кэширования. Вот пример того, как вы можете его использовать:

The old way using $resource:

var Entry = $resource('/entries/:slug', {slug: '@slug'});

var announcement = new Entry();
announcement.slug = 'announcing-angular-cached-resource';
announcement.title = 'Announcing Angular Cached Resource';
announcement.body = 'Here is why Angular Cached Resource is awesome!';

announcement.$save(function() {
  alert('Saved announcement.');
});

The new way using $cachedResource:

var Entry = $cachedResource('entries', '/entries/:slug', {slug: '@slug'});

var announcement = new Entry();
announcement.slug = 'announcing-angular-cached-resource';
announcement.title = 'Announcing Angular Cached Resource';
announcement.body = 'Here is why Angular Cached Resource is awesome!';

announcement.$save(function() {
  alert('Saved announcement.');
});

Единственные различия в коде:

Use $cachedResource instead of $resource Provide a "key" (entriesin the example above) so that you can refer to it even between page refreshes or reloads. These entries persist since out of the box it uses localStorage.

Подробное руководство доступно здесь:https://github.com/goodeggs/bites/blob/master/src/documents/open_source/2014-04-24-angular-cached-resource.md

Также обратите внимание, что Angular 2.0 может поддерживать что-то подобное из коробки:https://docs.google.com/document/d/1DMacL7iwjSMPP0ytZfugpU4v0PWUK0BT6lhyaVEmlBQ/edit

Я использую angular-resource 1.5.5 и настраиваю свой код следующим образом:

Summary

Задаватьaction какqueryи так как «запрос» action ожидает ответа, десериализованного в виде массива, для isArray необходимо явно установить значение true. Насколько я понимаю, по умолчанию действия ngResource ожидают объекты, кроме запроса. Посмотреть здесь

Controller

angular.module("app")
    .controller('myCtrl',['$scope','myService',function($scope, myService) {
        $scope.myData= myService.myResource.query();
    }]);

Service

angular.module('app')
    .factory('myService',['$resource',function($resource){
        var baseUrl = 'http://www.MyExample.com/';
        return{
            myResource:$resource(baseURL + '/myEndpoint/:id', {id:'@id'},{
                'query':{
                    method:'GET',
                    cache:'true',
                    isArray:true
                }}),
        }
    }]);

Просмотр источника углового ресурса показывает, что запуск кэширования невозможен при том способе, которым оно написано в настоящее время.

Вот объект запроса из источника:

$http({
    method: action.method,
    url: route.url(extend({}, extractParams(data), action.params || {}, params)),
    data: data
 }).then(...)

Есть несколько потенциальных способов справиться с этим.

Во-первых, вы можете кэшировать локально, используя постоянство на стороне клиента. я используюamplify.store с оберткой (b / c, мне действительно не нравится синтаксис API). Существуют различные другие решения для хранения данных, в зависимости от того, что вы ищете и какой браузер вы используете. Довольно много людей используютшезлонге также.

Затем вы можете структурировать и хранить свои модели локально и обновлять их в соответствии с любыми правилами или сроками, которые вы пожелаете.

Другое решение состоит в том, чтобы просто изменить угловой ресурс, чтобы он соответствовал параметрам, которые вы ищете. Это может быть так просто (просто добавить дополнительный аргумент в $ resource) или сложным, как вам нужно.

например

function ResourceFactory(url, paramDefaults, actions, cache) {
   ...
   var cache = cache != null ? cache : false; // Set default to false
   $http({
        method: action.method,
        url: route.url(extend({}, extractParams(data), action.params || {}, params)),
        data: data,
        cache: cache
    }).then(...)       
}

Наконец, в зависимости от ваших требований, может быть значительно проще создать собственный ресурс, используя angular.factory для создания сервиса. Одним из преимуществ ngResource является то, что он выполняет всю интерполяцию строк при преобразовании параметров. Однако вы, безусловно, можете использовать эту логику для анализа, если вам это нужно, или написать свою собственную на основе моделей, которые вы используете.

 20 авг. 2013 г., 15:40
А как насчет jsstorage, вы бы использовали его против ampify.store?
 07 сент. 2013 г., 00:21
Не пробовал, но, глядя на синтаксис и набор функций, он мне больше нравится, чем в Amplify. Прошло некоторое время с тех пор, как я посмотрел на любой из них, поскольку недавно я не писал код для старых браузеров (и, таким образом, просто использовал облегченную оболочку localStorage).
Решение Вопроса

С 1.1.2 (совершить) все параметры $ httpConfig напрямую отображаются в объектах действия $ resource:

return {
  Things: $resource('url/to/:thing', {}, {
    list : {
      method : 'GET',
      cache : true
    }
  })
 };
 03 мая 2013 г., 10:39
Может быть, вы можете открыть новый вопрос и привести пример?
 01 мая 2013 г., 23:54
Пробовал использовать это в 1.1.4 и не получилось :(
 04 сент. 2013 г., 11:28
Вы можете извлечь соответствующие изменения из файлов $ resource (которые не являются частью ядра) и вставить их в стабильную ветку. Поскольку ветка 1.1.x по моему опыту очень стабильна, я могу рекомендовать ее использовать. В любом случае, это одно из возможных решений проблемы, а не однозначный ответ.
 04 сент. 2013 г., 04:00
Это не очень хороший ответ. Текущая стабильная версия AngularJS - 1.0.7, и есть несколько рабочих мест, которые используют более старые версии. Как нам обойти это, если мы не используем 1.1.2?

Вы также можете установить кеш по умолчанию для $ http и, следовательно, для $ resource, который основан на нем.

Мои настройки с отличнымУгловые кэша разрешение LocalStorage и совместимое с $ cacheFactory:

app.run(function($http, DSCacheFactory) {

    DSCacheFactory('defaultCache', {
        deleteOnExpire: 'aggressive',
        storageMode: 'localStorage' 
    });

    $http.defaults.cache = DSCacheFactory.get('defaultCache');
});

Ваш ответ на вопрос