I'm a new user to AngularJS and ui-router, and I'm trying to turn my head around on how the scope is managed. I was expecting the scope of an active controller would be destroyed when it becomes inactive on state change, however, it doesn't appear to be the case.
I've modified the example from UI-Router's website to illustrate the situation (see plunker below). Every time when the state route1.list/route2.list is triggered, they will emit an event on $rootScope. On receiving the event, a debug statement will be printed to console.
By toggling between the two states a few times, it is observed that all the controllers initialized previously responded the the event. So it appears that the scopes created by them have never been destroyed. Is this behavior expected? If so, what should I do such that only active controllers will respond to an event?
Plunker
Debug message printed on Console:
Code:
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/route1")
here is the route1
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html"
})
.state('route1.list', {
url: "/list",
templateUrl: "route1.list.html",
controller: function($rootScope, $scope){
$rootScope.$emit("eventCT1");
$rootScope.$on("eventCT2", fn);
function fn () {
console.log("Controller 1 receives an event emitted by Controller 2");
}
$scope.items = ["A", "List", "Of", "Items"];
}
})
and here is route 2
.state('route2', {
url: "/route2",
templateUrl: "route2.html"
})
.state('route2.list', {
url: "/list",
templateUrl: "route2.list.html",
controller: function($rootScope, $scope){
$rootScope.$emit("eventCT2");
$rootScope.$on("eventCT1", fn);
function fn () {
console.log("Controller 2 receives an event emitted by Controller 1");
}
$scope.things = ["A", "Set", "Of", "Things"];
}
})
...
If we want to do something with
1) $rootScope
inside of the controller (which has very limited lifetime),
2) we must destroy that, when controller (its $scope
in fact) is being destroyed
So, this is the way how to hook and unhook
// get remove function
var removeMe = $rootScope.$on("eventCT2", ...);
// call that function
$scope.$on("$destroy", removeMe)
But, in the case above, we should not even try to
1) create some controller action for one state...
2) and expect it will be called in another controller from different state
These will never live together
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With