<h1>Example: Pub/Sub</h1>
<p>$emitと$broadcastを使ってスコープ間連携を実現します。</p>
<div ng-app="myApp">
  <div ng-controller="mainController as main" class="ctrl">
    <h2>mainController</h2>
    <p>Message: {{ main.message }}</p>
    <p>{{ main.count }}</p>
    
    <div ng-controller="emitController as emit" class="ctrl left">
      <h3>emitController</h3>
      <p>$emitは自身と親のコントローラーにイベントを伝達する。</p>
      <p>Message: {{ emit.message }}</p>
      <p>{{ emit.count }}</p>
      <button ng-click="emit.countUp()">CountUp</button>
    </div>

    <div ng-controller="broadcastController as broadcast" class="ctrl right">
      <h3>broadcastController</h3>
      <p>$broadcastは自身と子のコントローラーにイベントを伝達する。</p>
      <p>Message: {{ broadcast.message }}</p>
      <p>{{ broadcast.count }}</p>
      <button ng-click="broadcast.countUp()">CountUp</button>
      
      <div ng-controller="childController as child" class="ctrl">
        <h4>childController</h4>
        <p>Message: {{ child.message }}</p>
        <p>{{ child.count }}</p>
      </div>
      
      <div ng-controller="childController as child" class="ctrl">
        <h4>childController</h4>
        <p>Message: {{ child.message }}</p>
        <p>{{ child.count }}</p>
      </div>
    </div>
   </div>
</div>
@import "bourbon";

body {
  padding: 1.5rem;
  
  font-size: .8em;
}

.ctrl {
  @include clearfix();
  padding: .5rem;
  border: 1px solid #aaa;
  box-sizing: border-box;
  
  &.left {
    float: left;
    width: 50%;
  }
  
  &.right {
    float: right;
    width: 50%;
  }
}
View Compiled
(function() {
  "use strict";

  var appName = 'myApp';

  angular
    .module(appName, []);

  angular
    .module(appName)
    .controller('mainController', mainCtrl)
    .controller('emitController', emitCtrl)
    .controller('broadcastController', broadcastCtrl)
    .controller('childController', childCtrl);

  function mainCtrl($scope){
    var vm = this;

    vm.count = 0;
    $scope.$on('CountEvent', countEvent);

    function countEvent(event, data){
      vm.count++;
      vm.message = data;
    }
  }

  function emitCtrl($scope){
    var vm = this;

    vm.count = 0;
    vm.countUp = countUp;
    $scope.$on('CountEvent', countEvent);

    function countUp(){
      $scope.$emit('CountEvent', '$emit: +1');
    }

    function countEvent(event, data){
      vm.count++;
      vm.message = data;
    }
  }

  function broadcastCtrl($scope){
    var vm = this;

    vm.count = 0;
    vm.countUp = countUp;
    $scope.$on('CountEvent', countEvent);

    function countUp(){
      $scope.$broadcast('CountEvent', '$broadcast: +1');
    }

    function countEvent(event, data){
      vm.count++;
      vm.message = data;
    }
  }

  function childCtrl($scope){
    var vm = this;

    vm.count = 0;
    $scope.$on('CountEvent', countEvent);

    function countEvent(event, data){
      vm.count++;
      vm.message = data;
    }
  }
})();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js