title: Inter-Controller communication, the angular way
body: <p>I'm trying to figure out the "preferred" or "angular-way" of sharing properties or state between controllers/directives. There are several methods to implement this, but I want to keep with best-practice. Below are some banal examples of how this can be implemented:</p>
  
  <hr>
  
  <p><strong>1. Using $scope.$watch</strong> </p>
  
  <pre><code>// The parent controller/scope
  angular.module('myModule').controller('parentController', ['$scope', function($scope) {
      $scope.state = {
          myProperty: 'someState'; // Default value to be changed by some DOM element
      };
  }]);
  
  // The child controller/scope.
  angular.module('myModule').controller('childController', ['$scope', function($scope) {
      $scope.$watch('state.myProperty', function (newVal) {
          // Do some action here on state change
      });
  }]);
  </code></pre>
  
  <p><em>Edit</em>: Based on answers below, this is bad practice and should be avoided. It is untestable and places an unwanted DOM dependancy.</p>
  
  <hr>
  
  <p><strong>2. Using $broadcast</strong></p>
  
  <pre><code>// The parent controller
  angular.module('myModule').controller('parentController', ['$scope', function($scope) {
      var myProperty = 'someState';
      $scope.setState = function (state) {
          myProperty = state; // Set by some other controller action or DOM interaction.
          $scope.$broadcast('stateChanged', state); // Communicate changes to child controller
      }
  }]);
  
  // The child controller.
  angular.module('myModule').controller('childController', ['$scope', function($scope) {
      $scope.$on('stateChanged', function (evt, state) {
          // Do some action here
      }
  }]);
  </code></pre>
  
  <p><em>Edit</em>: Equally bad practice as you need to know the placement of the controllers in the DOM in order to determine weather to use $broadcast (down the DOM) or $emit (up the DOM).</p>
  
  <hr>
  
  <p><strong>3. Using service</strong></p>
  
  <pre><code>angular.module('myModule').factory('stateContainer', [function () {
      var state = {
              myProperty: 'defaultState'
          },
          listeners = [];
  
      return {
          setState: function (newState) {
              state.myProperty = newState;
              angular.forEach(listeners, function (listener) {
                  listener(newState);
              });
          },
          addListener: function (listener) {
              listeners.push(listener);
          }
      }
  }]);
  
  // The parent controller
  angular.module('myModule').controller('parentController', ['$scope', 'stateContainer', function($scope, stateContainer) {
      $scope.setState = function (state) {
          stateContainer.setState(state);
      };
  }]);
  
  // The child controller.
  angular.module('myModule').controller('childController', ['$scope', 'stateContainer', function($scope, stateContainer) {
      stateContainer.addListener(function (newState) {
          // Do some action here
      });
  }]);
  </code></pre>
  
  <p>There are probably some approaches I've missed here, but you get the idea. I'm trying to find the <em>best</em> approach. Although verbose, I personally lean towards #3 in the list here. But I come from a Java and jQuery background where listeners are widely used.</p>
  
  <p><em>Edit</em>: Answers below are insightful. One talks of sharing state between parent/child directives using the <code>require</code> directive configuration. The other talks of sharing service or service properties directly to the scope. I believe that depending on the need, they are both right in what is or is not best practice in Angular. </p>