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

42

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

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

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

Увидетьgroups.google.com/d/msg/angular/K_PoqLcOiuo/OkDpVrz7HsEJ Mark Rajcok
Единственный ответ прямо сейчас - «внедри его сам» до следующей версии угловой. Вы можете использовать эту реализацию, которая находится в PR:github.com/angular/angular.js/pull/1045 Andrew Joslin
Что ж, это не решает проблему, "внедрите ее самостоятельно" это не то, что он и я ищем DerWaldschrat

Ваш Ответ

8   ответов
59

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

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

Как утверждают документы,$ ресурсов имеет встроенную поддержку$ 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 }
    });
});
Спасибо, я соответственно обновил свой ответ.
Вы должны передать экземпляр Cache (созданный с $ cacheFactory), а не сам $ cacheFactory.
0

Я только что наткнулся на этот действительно хорошо продуманный модуль 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.');
});

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

  1. Use $cachedResource instead of $resource
  2. 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

0

Я использую 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
                }}),
        }
    }]);
56

Реализовать свой собственный кеш в 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;
      }
   };
});
На самом деле, $ resource теперь имеет встроенную поддержку кеша. Не нужно продолжать делать это вручную.
0

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

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

$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 является то, что он выполняет всю интерполяцию строк при преобразовании параметров. Однако вы, безусловно, можете использовать эту логику для анализа, если вам это нужно, или написать свою собственную на основе моделей, которые вы используете.

А как насчет jsstorage, вы бы использовали его против ampify.store?
Не пробовал, но, глядя на синтаксис и набор функций, он мне больше нравится, чем в Amplify. Прошло некоторое время с тех пор, как я посмотрел на любой из них, поскольку недавно я не писал код для старых браузеров (и, таким образом, просто использовал облегченную оболочку localStorage).
6

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

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

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

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

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

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

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

Похожие вопросы