どうも、なかたです。
AngularJSのコントローラー(スコープ)間のデータやりとりで使われる、
「$on」、「$emit」、「$broadcast」
今回はこれらについてまとめてみた。
$on
イベント監視を行う
指定のイベントが発生した際に実行されるリスナーを登録できる
scope.$on('eventname', function(event, args) { ... });
$emit
自分を含む上方向(親方向)へのイベント通知
イベントと一緒にデータも渡すことができる
scope.$emit('eventname', args);
$broadcast
自分を含む下方向(子方向)へのイベント通知
イベントと一緒にデータも渡..(ry
scope.$broadcast('eventname', args);
そもそも親子ってなんなのよ?
コントローラーが入れ子になっている場合、AngularJSは
外側のコントローラーを親、内側を子としてみる
<div ng-controller="Ctrl1"> <a href="#" ng-click="click()">click1</a> </div> <div ng-controller="Ctrl2"> <a href="#" ng-click="click()">click2</a> </div>
<div ng-controller="Ctrl1"> <a href="#" ng-click="click()">click1</a> <div ng-controller="Ctrl2"> <a href="#" ng-click="click()">click2</a> </div> </div>
Ctrl2がCtrl1の内側に入ってますね。
これで親子関係となります。
実際に動かしてみよう
<!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="Ctrl1"> <a href="#" ng-click="click()">click1</a> <div ng-controller="Ctrl2"> <a href="#" ng-click="click()">click2</a> </div> </div> </body> </html>
angular.module("app", []) .controller("Ctrl1", function($scope) { $scope.$on("event:test", function(event, args) { console.log("controller1", args); }); $scope.click = function() { $scope.$emit("event:test", "data1"); }; }) .controller("Ctrl2", function($scope) { $scope.$on("event:test", function(event, args) { console.log("controller2", args); }); $scope.click = function() { $scope.$emit("event:test", "data2"); }; });
結果を見てみよう
$emitになってるので、
– click1を押下 → “controller1 data1” がログに出力される
– click2を押下 → “controller1 data2” と “controller2 data2” がログに出力される
たしかに”自分を含む上方向(親方向)へのイベント通知”されてるのがわかります。
$emitを$broadcastに変更すると動きが逆になるはずです。
感謝サイト
http://kinjouj.github.io/2014/04/angularjs-17-broadcast.html
http://kinjouj.github.io/2014/04/angularjs-18-emit.html