1

I have a left sidebar in my webpage and his controller always working in the background. On the remaining side i have view of states that depends on the left side of the view (classic ui-view situation). I want to change variables in the sidebar's controller from the other controller. both active on the same time. I don't want to use $rootScope.

What is the best way to implement that?

Mistalis
  • 17,793
  • 13
  • 73
  • 97
  • Maybe the best way is to init the vars in a directive and share them between the controllers – Ferus7 May 04 '17 at 12:59
  • Possible duplicate of [Relation between two controller in angular](http://stackoverflow.com/questions/28959553/relation-between-two-controller-in-angular) – Burak Akyıldız May 04 '17 at 13:00
  • @BurakAkyıldız One your link, the accepted answer use $scope events. It would be better to store it into a service. See [**my answer**](http://stackoverflow.com/a/43783633/4927984). – Mistalis May 04 '17 at 13:14

2 Answers2

3

The right way is to use a service in order to share data/functions between controllers.

In the following example, changing the data in the MainCtrl also update the SidebarCtrl:

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

myApp.factory('Data', function() {
    return { FirstName: '' };
});

myApp.controller('SidebarCtrl', function($scope, Data) {
    $scope.Data = Data;
});

myApp.controller('MainCtrl', function($scope, Data) {
    $scope.Data = Data;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
    <div ng-controller="SidebarCtrl">
        <h4>SidebarCtrl</h4>
        Data is: <strong>{{Data.FirstName}}</strong>
    </div>
    <hr>
    <div ng-controller="MainCtrl">
         <h4>MainCtrl</h4>
        <input type="text" ng-model="Data.FirstName">
        Data is: {{Data.FirstName}}
    </div>
</div>
Mistalis
  • 17,793
  • 13
  • 73
  • 97
  • Thank u very much, that's exactly what I was looking for, well almost. I showing a table at my MainCtrl and after deleting,edding and adding some row i call the server to get the new table, and i want to see the changes also on the SideBarCtrl. – Trying_To_Know May 07 '17 at 09:38
0

1st way: use services

Services are singletons and you can pass data through services. For example, let's call our service dataservice:

angular
  .module('app')
  .controller('FirstController', ['dataservice']);

function FirstController(dataservice) {
  dataservice.dataToPass = 'data to pass through controllers';
}

And you can get this data from second controller like this:

angular
  .module('app')
  .controller('SecondController', ['dataservice']);

function SecondController(dataservice) {
  let dataFromFirstController = dataservice.dataToPass;
}

2nd way: use $emit/$broadcast (only if controllers are the parent and the child)

You can pass data up via $emit or down via $broadcast ($emit and $broadcast works similar, I'll show the example only with $broadcast). If FirstController is the parent and SecondController is the child, you can pass data through them like this:

angular
  .module('app')
  .controller('FirstController', ['$scope']);

function FirstController($scope) {
  $scope.$broadcast('passDataFromParentToChild', 'Data from FirstController');
}

And get data in SecondController:

angular
  .module('app')
  .controller('SecondController', ['$scope']);

function SecondController($scope) {
  $scope.$on('passDataFromParentToChild', function (event, data) {
    console.log(data); // will be "Data from FirstController"
  });
}

3rd way: use $scope.$parent (only if controllers are the parent and the child)

If you want to change variable of parent controller from the child controller, here is the easiest way (let's assume that FirstController is the parent of SecondController):

angular
  .module('app')
  .controller('FirstController', ['$scope']);

function FirstController($scope) {
  $scope.varFromParentController = 'First';
}

Let's change $scope.varFromParentController from SecondController:

angular
  .module('app')
  .controller('SecondController', ['$scope']);

function SecondController($scope) {
  $scope.$parent.varFromParentController = 'Second';
}
P.S.
  • 15,970
  • 14
  • 62
  • 86
  • @Trying_To_Know, if you want to take advantages of `$scope`, sometimes using `$scope` is better than `var vm = this` way – P.S. May 10 '17 at 12:41