Reputation: 864
I defined m my application states using ui-router:
$stateProvider
.state('app', {
abstract: true,
views: {
'nav@': {
templateUrl: 'app/navbar.html',
controller: 'NavbarController',
controllerAs: 'vm'
},
'main@': {
template: '<div ui-view></div>'
}
}
})
.state('child1', {
url: '/child1',
parent: 'app',
templateUrl: 'app/child1.html',
controller: function($timeout) {
$timeout(function() {
alert('from child_1');
}, 15000)
},
controllerAs: 'vm'
})
.state('child2', {
url: '/child2',
parent: 'app',
templateUrl: 'app/child2.html',
controller: 'ctrl_2',
controllerAs: 'vm'
})
When I go from /child1
to /child2
quickly (before 15000 miliseconds), still I see the alert that was defined in child1
controller, is this a normal behavior?
Upvotes: 0
Views: 216
Reputation: 48968
is this a normal behavior?
Yes, this is normal behavior. Function references created and given to another function (such as the $timeout
service) will last as long as the other function keeps that reference. In the case of the $timeout
service, it will keep that reference for the duration of the timeout (in this case 15 seconds).
In addition if the child function uses local variables of the parent function, those local variables will be retained for the life of the child function. That process is known as "creating a closure".
For more information, see MDN JavaScript Reference - Closures
The $timeout
service needs to be told to cancel the timeout and remove the reference or it will persist beyond the life of the controller.
controller: function($timeout, $scope) {
var promise = $timeout(function() {
alert('from child_1');
}, 15000);
$scope.$on("$destroy", function() {
promise.cancel();
});
},
In the above example, the $timeout
service attaches a function called cancel
to the promise that it returns. Client code can invoke that function to tell the $timeout
service to abort the timeout and release the reference to the function.
When the ui-router
switches from child1
state to another state, it destroys the scope of the controller. The controller should listen for the $destroy
event and cancel the timeout.
Upvotes: 2