Trying_To_Know
Trying_To_Know

Reputation: 33

Right way to work with two controllers at the same time?

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?

Upvotes: 1

Views: 229

Answers (2)

P.S.
P.S.

Reputation: 16384

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';
}

Upvotes: 0

Mistalis
Mistalis

Reputation: 18279

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>

Upvotes: 3

Related Questions