Реализация кеша на фабрике в AngularJS

В настоящее время я пытаюсь внедрить службу кэширования в мое угловое приложение, чтобы уменьшить нагрузку на конечную точку и (надеюсь) увидеть небольшое, возможно, незначительное время загрузки моего интерфейса.

Я начал с реализации моей собственной cacheService который в значительной степени является оберткой для $cacheFactory

(function () {
    'use strict';

    angular
        .module('app')
        .factory('cacheService', cacheService);

    cacheService.$inject = ['$cacheFactory']

    function cacheService($cache) {
        return $cache('appCache');
    }
})();

Тогда у меня есть datacontext которая по сути является единицей работы, которая потребляет мой cacheService а также $http (У меня там есть несколько других "репозиториев", но я показал только тот, с которым я пытаюсь заставить работать)

(function () {
    'use strict';

    angular
        .module('app')
        .factory('datacontext', datacontext);

    datacontext.$inject = ['$http', 'cacheService', '$q'];

    function datacontext($http, cache, $q) {    
        var rulesRepo = (function () {
            var repo = {
                get: getRule,
                getAll: getAll
            };

            return repo;

            function getRule(ruleId) {
                // placeholder
            }

            function getAll() {
                var deferred = $q.defer();

                // check to see if we have data cached
                var rules = cache.get('rules');
                if (rules) { // if it's cached, return it
                    deferred.resolve(rules);
                } else { // otherwise get the data from the API, cache it and return it
                    $http.get('/api/rules')
                        .then(function (response) {
                            cache.put('rules', response.data);
                            deferred.resolve(response.data);                            
                        });
                }
                return deferred.promise;
            }
        })();    

        var service = {
            rules: rulesRepo
        };

        return service;
    }
})();

И тогда мой угловой контроллер, который потребляет datacontext

(function () {
    'use strict';

    angular
        .module('app')
        .controller('HomeController', HomeController);

    HomeController.$inject = ['$scope', 'datacontext'];

    function HomeController($scope, context) {    
        context.rules.getAll()
            .then(
                function (data) { // success
                    $scope.rules = data;
                },
                function (response) { // failure
                    console.log(response);
                });

        activate();
        function activate() { }
    }
})();

Проблема, с которой я сталкиваюсь на данный момент, заключается в том, что всякий раз, когда я звоню context.rules.getAll()всегда поражает else утверждение, смысл rules не определено, поэтому он никогда не использует кеш, он просто вызывает другой API, получает данные, кэширует их (эта часть работает, я проверил ее, извлекая из кеша сразу после помещения в кеш), а затем возвращает обещание. Вновь и вновь.

Может кто-то указать, где я не понимаю, как это должно работать?

1 ответ

Учитывая, что все фабрики в angular являются синглетонами, базовая реализация фабрики кэша будет выглядеть примерно так

app.factory(cacheFactory, function(){
  var localCache = {};
  var put  = function(key, value)     { localCache[key] = value;    }
  var get  = function(key)     { return localCache[key];    }
  return { get:get, put:put  } 
})

это должно работать, если вы не хотите поддерживать кеш даже при жестком обновлении.

Другие вопросы по тегам