I’ve been using Angular JS for a few months now and started doing more and more with it. Quickly, I ended up having reusable widgets with their own controllers. When I wanted to use them within another app (page), I included them and ran into another problem. I wanted to be able to expose functions or pass data between them. For example, one controller managed a generic set of data provided by some AJAX request. That table would be embedded within another page.
angular.module('myPage', ['tableWidget']).controller(...)
I had a special case where I wanted to lazy-load some details of the table, but had no way for the main controller to access the scope of the tableWidget controller. I dug around a bit and found I could use $emit and $on to pass events. For example, on the re-usable tableWidget controller, when data had finished loading, I would emit an event.
$scope.$emit('itemsLoaded', $scope.items);
That happens every time the widget loads data, on every page. But, on my page, I wanted to know about that so I set up a listener.
$scope.on('itemsLoaded', function($event, items){ for (var i=0; i < items.length ; i++) { var item = items[i]; // do something with item } });
Pretty slick, right? Well, I had another problem. The table widget had a reload button to allow the user to cause another AJAX fetch without reloading the entire page. I needed to trigger that fetch from my main controller. I tried $emit, but no good. I finally found $broadcast.
$scope.$broadcast('refresh');
Within the table widget controller, I listened.
$scope.on('refresh', function($event) { // trigger the ajax call });
I hope this is helpful! It really allowed me to make the reusable components in my application much more useful!