5

I've got the next problem and I'd like to find a solution or if I should even be doing this like I am.

I have the following ui-router configuration:

$stateProvider.state('ListCounterparties', {
    url:"/counterparties",
    data: { NavMenuItem : 'Counterparties / Desks' },
    views: {
        '' : {
            templateUrl:"./app/module_Counterparties/templates/ListCounterparties.html",
            controller:"CounterpartiesControllerCtrl"
        },
        'deskLists@ListCounterparties' : {
            templateUrl : './app/module_Counterparties/templates/DesksDualListTemplate.html',
            controller:'DesksControllerCtrl'
        }
}

The first, unnamed view, has a table from which I can select a row and then a method will be called to populate a dual list from the second view.

Up until now, I've had both in the same controller, but the controller is getting too big and I decided I had to separate them.

The method to populate the dual lists in 'deskLists@ListCounterparties' is defined in DesksControllerCtrl but it should be called in CounterpartiesControllerCtrl, as the event of row selection is in that controller.

The problem is that the scopes are not shared and the method is inaccesible to the unnamed view.

Accessing the scope in DesksControllerCtrl I could see that accessing the $parent property twice I can get to the CounterpartiesControllerCtrl, but I don't thin that's an ideal thing to do.

Thanks in advance.

2
  • 1
    Do you want to share a real scope or just data? Commented Jan 21, 2016 at 10:44
  • Probably the scope as I'll be calling methods from one controller from the other. Commented Jan 21, 2016 at 10:46

1 Answer 1

3

Sharing data, methods, etc. between multiple controllers the Angular way would be to create service(s). That means, you create e.g. a service which holds all your data and another one which provides functionality for several controllers. Then, just inject them in your controllers:

var myApp = angular.module('myApp', []);

myApp.factory('myGlobalData', function() {
  return {
    data: 1
  };
});

myApp.factory('myService', function(myGlobalData) {
  return {
    increment: function() {
      myGlobalData.data++;
    }
  };
});

myApp.controller('MyCtrlA', function($scope, myGlobalData, myService) {
  $scope.myGlobalData = myGlobalData;
  $scope.myService = myService;
});

myApp.controller('MyCtrlB', function($scope, myGlobalData, myService) {
  $scope.myGlobalData = myGlobalData;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">

  <p ng-controller="MyCtrlA">
    {{myGlobalData.data}}
  </p>

  <p ng-controller="MyCtrlB">
    {{myGlobalData.data}}
  </p>

  <div ng-controller="MyCtrlA">
    <button ng-click="myService.increment()">Increment data in myGlobalData service</button>
  </div>

</div>

Sign up to request clarification or add additional context in comments.

3 Comments

That's a pretty simple and nice solution, as an only caveat I see that you have to inject two services to get the functionality working. That in big applications can get a bit messy, I've actually found a good scalable solution from one of the posts here at stack overflow, I'll post it later when I've got some more time. But you gave me the idea of actually sharing the data in a way other than inheriting scopes.
Well, I have injected the same myService in two different controllers. Sharing functionality globally by means of services, filters, etc is a basic idea of AngularJS.
If you don't inject the services, and using scope inheritance (invisible) I think than it will go messy in big applications... as you don't know what can access what.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.