epeleg epeleg - 5 months ago 15
AngularJS Question

where in an angular app is a good place to store "shared" data

This is somewhat a follow up on my "Is it bad practice for an angular directive to request data" Q.

My Q Is where would be the appropriate place to keep application data?
for example - information about the current user such as his name and his roles in the app?

differrent areas (on the screen) and components will depend on this data (e.g - side bar will want to know if the curentUser.isAnAdmin and a helloUser Directive would like to know the currentUser.name

Does this mean that the currentUser should be placed on the $rootScope?
and what should be the trigger for retrieving the initial data for the currentUser and for refreshing this information?

I was thinking of having several ngControllers responsible for setting up this data on the scope of the same html node as that of the ngApp, but found out that it is not possible to have multiple ngControllers on a single HTML Item.

I am now thinking of having multiple services with methods that get a scope object and assign the data they are responsible to onto that scope.
It would allow me to separate code for currentUser from code for someOtherSharedAppData into two different services and call both of them from the applications's main controller thus assiging the data to the scope associated with the top-most element in the app - does that make sense?

Answer

In fact you asked two questions here:

  1. Where to store and manipulate data?
  2. When and how should I use the $rootScope (compared to $scope)?

1) I will refer to this article: Whenever data and methods need to be reusable I would write a service like this for example.

angular.module('modelDemo').service("myModel", [function() {
    this.list = [what, ever, items, you, have];

    this.property= null;
    this.setProperty = function(value) {
        this.property= value;
    };
}]); 

Note, that I'm not passing the $scope as you considered. Instead I would inject the service in my controller and bind the $scope variables like this:

$scope.list = myModel.list;

If you need, you can even bind to the full model

$scope.myModel = myModel;
myModel.setPropery(value)

Got the idea? This way all model changes will be directly available to the corresponging view

{{myModel.property}}
ng-repeat="item in myModel.list"
ng-click="myModel.setProperty(item)"

Conclusion: Yes, you should have different services for your user model and your someOtherSharedAppData models.

2) I will refer to this SO Question. In short: If you have data that should be available in many views, it is OK to bind your (service) model to $rootScope variables. As you can see in the mentioned discussion there are also other opinions but I think the conclusion is: It depends on the structure and needs of your application.