1

I am using AngularJs for a new application. I feel I have solved a problem but i'm not sure i have done it in the best way possible so would like to check before gunning ahead.

Let's for examples sake say i have the two controllers AccountsCtrl and ContactsCtrl, every time each is called a request to a REST server for all the accounts or contacts is made for each controller respectively. When within the controller any data changes are kept in sync in the angular models (and the server backend) to reflect this and hence the UI. Every time the user switches between each controller they have to make call to the server to fetch the data which it already had (which was up to date) last time it was loaded.

Currently this causes a very small lag. I would like to make it persistant i.e. not loaded each time the controller is loaded to save on the lag and the server requests. I have tried saving the data into the $rootScope and this works great but i'm not sure it's the right thing to do?

The question is how best solve this problem? Is the $rootScope the best way to tackle this?

NimmoNet
  • 994
  • 2
  • 10
  • 18

2 Answers2

2

I would store the data and code that interacts with the web server in one or two Angular services. Each time a controller is created (e.g., when you go back to the page a second time), the (appropriate) service should decide whether to return the cached data or make an Ajax request to your REST server.

Your service(s) would be injected into your controllers.

See also https://stackoverflow.com/a/12009408/215945 and https://groups.google.com/d/topic/angular/eegk_lB6kVs/discussion

Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
0

First of all, you should do your REST call via a service:

app.factory('RestService', ['$http', function($http) {
   return {
     getSomething: function(url) {
        var result = {};

        $http.jsonp(url).success(function(data) {
           result.list = data;
        });
        return result;
     }
   };
   ...
}];

You don't need $rootScope. Just define a parent controller which scopes both controllers, e.g. RootController, and store the data there. This is because child scopes (e.g. from AccountsCtrl) inherit what is defined in parent scopes.

<div ng-controller="RootController">
    <div ng-controller="AccountsCtrl">
    </div>
    <div ng-controller="ContactsCtrl">
    </div>
</div>

In practice this is almost the same as using $rootScope, but you don't need to inject it and you keep your controller logic similar as other controllers.

asgoth
  • 35,552
  • 12
  • 89
  • 98
  • I am actually using a Resource for the REST communications at the moment. But would love to see how Factory for the REST comms would be implemented fully do you have an example. Secondly i don't want to blanket turn caching on as there are many calls which should not be cached. – NimmoNet Jan 10 '13 at 13:06
  • I've added an extra paragraph in my answer. It is better practice to add a parent controller and define the service there. – asgoth Jan 10 '13 at 13:14
  • Hi thanks again for the answers... I don't understand quite how this works. Quickly testing in my app setting a variable in the rootCtrl does allow access in the child controllers e.g. ContactsCtrl. Would you also be able to give me a full example of how the RestService would look for a get and post – NimmoNet Jan 10 '13 at 13:22
  • Added the RestService example – asgoth Jan 10 '13 at 13:41
  • ... techinically $resource *is* a service. Abstracting something out to a service is *almost* always a good idea, but not *always* necessary. – Ben Lesh Jan 10 '13 at 13:54
  • Looking in to the solutions further using a cache will not work as after making a call to the server and the data is changed the next time the controller is loaded it will fetch the cached result and not the altered data i.e. it won't be in sync. – NimmoNet Jan 10 '13 at 14:01
  • With all of the answer edits it is difficult to follow the comments. E.g., comments mention "blanket turn on caching", yet there is no mention of it in the answer that we see. Consider using strikethrough or adding new "Updated:" sections so that future readers can more easily follow along. – Mark Rajcok Jan 10 '13 at 16:06
  • @MarkRajcok: Indeed, sorry about that. Part of the answer was that sometimes a $http service can be cached using cache: true or with $cacheFactory. – asgoth Jan 10 '13 at 17:48