angular.jsをやってみる (17) - $broadcast -

2014-04-04T00:00:00+00:00 angular.js JavaScript

公式リファレンス: http://docs.angularjs.org/api/ng/type/$rootScope.Scope

※ややこしいので公式リファレンス読むかググった方が良い

node.jsのEventEmitter的なのという説明が正しいかは知らないけど、そんな感じでイベント通知による処理を促したり出来る模様。で今回は$broadcastのみ。$emitは次回(ややこしいので)

index.html

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.4/angular.min.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
    <div ng-controller="Controller1">
      <a href="#" ng-click="click()">click1</a>
    </div>
    <div ng-controller="Controller2">
      <a href="#" ng-click="click()">click2</a>
    </div>
  </body>
</html>

コントローラーを2つ利用するようにしておいて、そこでクリックで処理が発生させるだけ。んまぁ特にいう事もないので(ry

app.js

angular.module("app", [])
  .controller("Controller1", function($scope) {
    $scope.$on("a", function(event, args) {
      console.log("c1");
    });
    $scope.click = function() {
      $scope.$broadcast("a", "A");
    };
  })
  .controller("Controller2", function($scope) {
    $scope.$on("a", function(event, args) {
      console.log("c2");
    });
    $scope.click = function() {
      $scope.$broadcast("a", "A");
    };
  });

てな感じでクリックイベントにおいて$broadcastで飛ばす。んでそれを$scope.$onで受け取るっていう感じなのだが

上記のHTMLの構成だとController1でクリックした際にController2の$onは発生しない。という事でHTMLを

<div ng-controller="Controller1">
  <a href="#" ng-click="click()">click1</a>
  <div ng-controller="Controller2">
    <a href="#" ng-click="click()">click2</a>
  </div>
</div>

という事でController2をController1でネストさせて上げるとController1のclickから$broadcastをするとController2の$onの方まで伝播されるようになる

解説サイトによると「$broadcastは自分自身と子孫内のイベントをfireする」っていう事らしいので、Controller2をController1でネストする事によりController2がController1の子孫内っていう扱いにより子孫内におけるイベントがfireされるっていう事なのかも

つまりは$broadcastを呼ぶコンテキストなスコープから下への子孫スコープの方にはイベントが作用するっていう感じかと。まぁ上記の場合だとController2から発生する$broadcastがController1の方へ伝播されるようにはならない(方向が上な為かと)

ややこしいですが、んまぁそんな感じでイベントな伝播したりとか出来る模様で

次回はそれと似た$emitを書く予定

SlidingPaneLayout angular.jsをやってみる (16) - ngAnimate#2 -