Reputation: 1567
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?
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"];
}
})
...
Upvotes: 9
Views: 8363
Reputation: 1031
If you are using Ionic with Angular, you could use the life cycle events like so:
$scope.$on("$ionicView.beforeEnter", function(){
//Do something every time this controller is the active scope.
})
You could play around with the other events provided in the above link as well. And it's probably best practise to minimize the use of $emit
, which will lead to more predictable code and fewer state mutations.
Upvotes: -1
Reputation: 123861
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
Upvotes: 5