29

I have the following two peer controllers. There's no parent to these:

<div data-ng-controller="Controller1">

</div>

<div data-ng-controller="Controller2">
   The value of xxx is: {{ xxx }}
</div>

angular.module('test')
   .controller('QuestionsStatusController1',
    ['$rootScope', '$scope'
    function ($rootScope, $scope) {
    // How can I set the value of xxx in the HTML that's part of Controller2    
    }]);

angular.module('test')
   .controller('QuestionsStatusController2',
    ['$rootScope', '$scope',
    function ($rootScope, $scope) {
    }]);

In controller 1 I want to update the value of the variable xxx in the HTML that's controlled by Controller2. Is there a way I can do this?

4 Answers4

41

Use a service to achieve this:

MyApp.app.service("xxxSvc", function () {

var _xxx = {};

return {
    getXxx: function () {
        return _xxx;
    },
    setXxx: function (value) {
        _xxx = value;
    }
};

});

Next, inject this service into both controllers.

In Controller1, you would need to set the shared xxx value with a call to the service: xxxSvc.setXxx(xxx)

Finally, in Controller2, add a $watch on this service's getXxx() function like so:

  $scope.$watch(function () { return xxxSvc.getXxx(); }, function (newValue, oldValue) {
        if (newValue != null) {
            //update Controller2's xxx value
            $scope.xxx= newValue;
        }
    }, true);
kmdsax
  • 1,361
  • 9
  • 12
22

Definitely use a service to share data between controllers, here is a working example. $broadcast is not the way to go, you should avoid using the eventing system when there is a more appropriate way. Use a 'service', 'value' or 'constant' (for global constants).

http://plnkr.co/edit/ETWU7d0O8Kaz6qpFP5Hp

Here is an example with an input so you can see the data mirror on the page: http://plnkr.co/edit/DbBp60AgfbmGpgvwtnpU

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

testModule
   .controller('QuestionsStatusController1',
    ['$rootScope', '$scope', 'myservice',
    function ($rootScope, $scope, myservice) {
       $scope.myservice = myservice;   
    }]);

testModule
   .controller('QuestionsStatusController2',
    ['$rootScope', '$scope', 'myservice',
    function ($rootScope, $scope, myservice) {
      $scope.myservice = myservice;
    }]);

testModule
    .service('myservice', function() {
      this.xxx = "yyy";
    });
Craig Squire
  • 2,141
  • 14
  • 13
  • 3
    but is this not making two separate calls to the service? I mean, if the service would be an http request, wouldn't it create two separate http requests for the same data? – Eduardo La Hoz Miranda Nov 16 '15 at 20:52
  • I cannot send "yyy" or hard coded data i need to read from QuestionsStatusController1 and then pass to QuestionsStatusController2. –  Jan 13 '17 at 12:10
  • How i can send a image from one controller to another controller ? – Ayush Mishra Jul 11 '17 at 18:55
  • You should use Factory for data sharing, not service.When you’re using a Factory you create an object, add properties to it, then return that same object. But in case of Service it’s instantiated with the ‘new’ keyword ie new Object. – Mangesh Bhapkar Jun 06 '18 at 17:38
17

In one controller, you can do:

$rootScope.$broadcast('eventName', data);

and listen to the event in another:

$scope.$on('eventName', function (event, data) {...});
Jim Cote
  • 1,746
  • 3
  • 15
  • 26
4

You need to use

 $rootScope.$broadcast()

in the controller that must send datas. And in the one that receive those datas, you use

 $scope.$on

Here is a fiddle that i forked a few time ago (I don't know who did it first anymore

http://jsfiddle.net/patxy/RAVFM/

Deblaton Jean-Philippe
  • 11,188
  • 3
  • 49
  • 66
  • 2
    You don't 'need' to use `$broadcast`, `$emit`, or `$on` I actually prefer services because these methods create loose spaghetti messages sprinkled everywhere in the code - Basically a service encompasses these into one place with related 'events'. – Nate-Wilkins May 07 '14 at 17:45
  • this does not work in https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js – Rizwan Patel Jul 12 '16 at 13:52
  • 2
    I think this is the video tutorial for the above posted fiddle. [Communicating between Controllers](https://www.youtube.com/watch?v=1OALSkJGsRw) – Chris22 Sep 26 '19 at 20:03