简体   繁体   中英

What is the best practice for using $resource and sharing the results across multiple controllers?

So, I've looked all over the place and can't find the answer I'm after.

I've recently learned a few new things and switched from having my services get and store shared data like this:

angular.module('myModule')
.service('stuffService', function(){
    var thisService = {
        stuff: {},
        getSomething: function(){
            var onSuccess = function(response){
                thisService.stuff = response.data;
            };
            var onError = function(response){
                alert('Doh!');
            };
            var promise = $http.get(<url>).then(onSuccess, onError);
            return promise;
        }
    };
    return thisService;
});

angular.module('myModule')
.controller('myController',function($scope, stuffService){
    $scope.stuff = stuffService.stuff;
});

to this:

angular.module('myModule')
.factory('stuffService', function(){
    var stuffResource = $resource(<stuff_url>, <params>, <etc>);
    return {
        stuff: stuffResource
    }
});

angular.module('myModule')
.controller('myController', function($scope, stuffService){
    $scope.stuff = stuffService.stuff.get(...);
});

This has been a really beneficial change in terms of most of the operation of my application; however, I'm running into a pickle as far as how would I share the data that the stuffResource returns.

Previously, I could just always reference stuffService.stuff from any controller that had stuffService injected into it. But now with $resource, I'm not sure how I would store this data. Using $scope.stuff or even $scope.stuff.get() would always run a query, and not act like an actual collection of "stuff".

At first, I tried to have a parent controller that did $scope.stuff = myService.stuff.get(...) and that actually worked really well... until I needed that same stuff outside of the parent controller. Now I need to figure out a way to store that data so that I'm not making the same API call over and over consecutively as the app loads up.

I've thought about turning on caching, which seems to be a pretty intuitive (duh!) approach but I'm not sure if that's the best course of action. Some data needs to be refreshed more often then others, so it would have to be caching with a cache limit of varying size/length and I'd be worried that some components would have different/newer data then components that loaded earlier. Maybe it feels like too simple of a solution, not sure. It would be nice if this was the answer, and I just used `stuffService.stuff.get()' just as if it was a stored object from the olden days.

I've also thought about using an interceptor to store this data similar to what my onSuccess method was doing previously. This seems ok too, but feels a little dirty/hacky. I would just need a little push to get this one working if I was on to a good idea.

My latest thought was to create a sort of "data service", that has the other services (like stuffService ) injected into it. This "dataService" would have an object that it loads up with data from all these other services and then can be shared as dataService.data.stuff . This is nice in that my data can be a single source that's shared throughout the app, but it's also yet another service that needs to be injected because I'll probably still need other methods from stuffService. This could work better if I had one stuffService with nonCRUD methods for stuff , and another crudStuffService which was basically a wrapper for $resource. I'd really prefer to have anything that related to stuff under the same service. When I was doing that before, it was really helpful to have things abstracted out like stuffService.getStuff() to make http requests or stuffService.findStuffWithSpecialConditions() to do loops and conditions, etc. on stored/shared data.

So, anyone got any ideas on how to get and store data using $resource within the same service? Is this how it should be done? Am I missing something?

Thanks!

For what you are looking is – flyweight patterrn

The most important part of its implementations will be:

.factory('stuffService', function(){
    var cache = {};
    var stuffResource = function(<stuff_url>, <params>, <etc>) {
        if(!cache[<stuff_url>+<params>+<etc>]) {
            cache[<stuff_url>+<params>+<etc>] = $resource(<stuff_url>, <params>, <etc>);
        }
        return cache[<stuff_url>+<params>+<etc>];
    }

    return {
        stuff: stuffResource
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM