Reputation: 909
I have two pieces of code in two separate Controllers (in two separate JS files); one triggers an Angular $scope.$broadcast
event, and the other an $scope.$on
listener.
First Controller (file) snippet:
var Controller1 = function($scope) {
$scope.triggerMyEvent = function(){
$scope.$broadcast('triggeredEvent');
}
$scope.go = function ( path ) {
$location.path( path );
};
}
Second Controller (file) snippet:
var Controller2 = function($scope) {
$scope.$on('triggeredEvent',function(event){
console.log('found triggered event');
});
}
The application is wired together as follows:
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/page2", {
controller : Controller2
template : "/page2.html"
})
.otherwise({
template : "<p>Error</p>"
});
});
The first Controller is referenced by a ng-controller
directive in the index.html file; and the other file, page2.html listed above is referenced and loaded from actions on the index:
index.html:
<body ng-controller="Controller1">
<button ng-click="go('/page2.html')">Page 2</button>
</body>
The first time I load up this code the $scope.$broadcast
event is triggered and the $scope.$on
listener catches it just fine; if I reload it though the $scope.$on
listener doesn't catch it. To be clear, on an initial load the event is triggered and caught just fine; so when restart my server and access the page. However if I refresh the page (F5), I believe the event is being fired but not caught. I'm new to working with this so I am presuming a some lack of knowledge however I have read up on $scope/$rootScope and things like $broadcast/$emit/$on. Any help is appreciated. I see a number of articles on related issues; not seeing anything imminently relevant; although I did note this article:
Angular $broadcast only updating after page refresh
AngularJS event-based communication through isolate scope
The most promising references I believe related to Isolate scope but I have not been able to get anything to work yet.
Upvotes: 1
Views: 1925
Reputation: 6652
$broadcast
and $on
work through the scope hierarchy. $broadcast
sends a message down the scope hierarchy toward it's descendants. Any $on
listeners must be a descendant of the scope that the message was broadcast from. If you broadcast from the $rootScope
, then every scope will be a descendant and every scope will be able to listen to the message. So, one way to ensure that your message is reachable by all scopes is to broadcast it like so:
// just to demostrate. don't put this in a controller
$scope.triggerMyEvent = function(){
$rootScope.$broadcast('triggeredEvent'); //don't do this in a controller
}
Ideally, you don't want litter root scope with messages. (Actually you should really never do this. It's even worse if you use $rootScope.$on
in a controller as it adds and retains a new listener everytime the controller is initialized). To get to the root of your problem(pun intended) you need to pay attention to this hierarchy, as this will affect your listeners.
One example of this hierarchy:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
</div>
</div>
<div ng-controller="SiblingCtrl">
</div>
function ParentCtrl($scope) {
$scope.$broadcast('parentMsg');
}
function ChildCtrl($scope) {
$scope.$on('parentMsg', function() {
// will receive message
});
}
function SiblingCtrl($scope) {
$scope.$on('parentMsg', function() {
// will not receive message
});
}
Upvotes: 1