3

I have a problem that I cannot find a proper answer to.

Ok I have data that i collect from api for example

Admin

User

user profile

user stats

For this I have

adminCtrl

userCtrl

userprofileCtrl

userstatsCtrl

The problem is when i in my controllers like if I I want to view userprofile then userprofileCtrl get routes from url like admins/:admin_id/users/:user_id/profile and I have to collect all the data like admin, user, and the profile in every controller to be able to print all the details in my view about the user.

Can I nest the controllers in some way? It leads to a lot of dry in controllers.

Also wondering what best practice for printing error messages is, i have apiservice wich makes all requests to my api, should i set the messages in service an how, rootScope?

  • 3
    I don't have a lot experience writing larger Angular applications yet, and I'm making assumptions about your layout (ngView w/ multiple controllers per view). That said, my guess is that you'd want a few layers of abstraction like `adminCtrl->UserService->UserDataService` and `userCtrl->UserService->UserDataService`. Where the UserService would keep the User information resident in-memory so that it can serve up other controllers without making duplicate requests to the server for data. – Langdon Apr 23 '13 at 18:05
  • +1 for using services http://docs.angularjs.org/guide/dev_guide.services – jackdbernier Apr 24 '13 at 20:34

4 Answers4

0

I think you need to have a look into angular-ui's ui-router directive.

It was specifically designed for nested routing.

https://github.com/angular-ui/ui-router

http://angular-ui.github.io/ui-router/sample/#/

marco alves
  • 1,707
  • 2
  • 18
  • 28
0

You can nest controllers in the view, so every child controller inherits parent's models.

Take a look at the angular docs at the 'Controller Inheritance Example': http://docs.angularjs.org/guide/dev_guide.mvc.understanding_controller

Controllers:

angular.module('App', [])
.controller('MainCtrl', ['$scope', function($scope){
    $scope.foo = 'foo';
}])
.controller('CtrlOne', ['$scope', function($scope){

}])
.controller('CtrlTwo', ['$scope', function($scope){
    $scope.foo = 'bar';
}]);

Then your view would look like this:

<div ng-app='App'>
    <div ng-controller='MainCtrl'>
        <div ng-controller='CtrlOne'>
            CtrlOne: {{foo}}
        </div>
        <div ng-controller='CtrlTwo'>
            CtrlTwo: {{foo}}
        </div>
    </div>
</div>

jsFiddle with the example above: http://jsfiddle.net/guilhermenagatomo/pAHR8/

A more complex way would be using a service to share the data between the controllers.

0

As said, you can nest controllers in the app - ie;

<div ng-controller='outercontroller'>
     <div ng-controller='innercontroller'>
     </div>
</div>

The inner controller can access whatever you have defined in the scope of the outer controller - it shadows the values of the outer controller. You could also access values in the outer controller through $scope.$parent, from the scope of the inner controller. This may help: Inheritance for scopes in AngularJS

Ideally, you should be using a service to retrieve your data and store it. You could then retrieve it from the service. An additional advantage is you could design the service to only refresh it's data if there have been any changes on the service, thereby saving you having to make a possibly redundant call. Socket.io could probably be used for this, or you could define a timer so it only refreshes after a set period.

As for error messages; I would probably create try/catch (or whatever you logic you intend to use for errors) blocks in the necessary places and pass an error code to a errorMessageService. In my view I would bind error parameters onto the service. If an error exists in the service, it will show the error in the view.

Community
  • 1
  • 1
Matthew Tyler
  • 316
  • 2
  • 7
0

1

In my opinion controller should only used to initiate scope states, data loading tasks should be move to angular.factory or angular.service depends on your needs. The benefits are:

  1. Services object exist in the application life cycle. You will deal with the same object all the time, so that you can keep the data around even if you route to another url or controller.
  2. Your data will be available anywhere
  3. Your don't have to worry about messing around with scope inheritance.

In some case you want to use ng-repeat in your html, you can just do:

app.run(function($rootScope) {
    $rootScope.yourDataService = yourDataService
}

So your ng-repeat will become:

<li ng-repeat="item in yourDataService.items"></li>

2

You can access $rootScope in service object, but if you followed the my first answer, you don't really have to worry about it. You can just attach the error message in your service object inside app.service then it will be available as $rootScope.yourDataService.errorMessage.

Daiwei
  • 40,666
  • 3
  • 38
  • 48