From 277a5ea05d50fb27243b98570c3ca9394b31e935 Mon Sep 17 00:00:00 2001 From: Josh Kurz Date: Thu, 12 Dec 2013 01:39:40 -0500 Subject: docs($interval): remind the developer to destroy their intervals It is essential that users of `$interval` destroy the interval when they are finished. Otherwise you can get memory leaks. Often `$intervals` are used in directives or controllers and developers don't think about what happens when the component is destroyed. If a directive/controller scope is destroyed, then the $interval should be destroyed as well. This could cause some issues with developers who assume that the interval will be cleared for them when the scope is destroyed. Closes #5377 I believe that the library could/should handle this as well, but thats another issue. --- src/ng/interval.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/ng/interval.js b/src/ng/interval.js index 1ae13648..bde4e25e 100644 --- a/src/ng/interval.js +++ b/src/ng/interval.js @@ -24,6 +24,14 @@ function $IntervalProvider() { * In tests you can use {@link ngMock.$interval#methods_flush `$interval.flush(millis)`} to * move forward by `millis` milliseconds and trigger any functions scheduled to run in that * time. + * + *
+ * **Note**: Intervals created by this service must be explicitly destroyed when you are finished + * with them. In particular they are not automatically destroyed when a controller's scope or a + * directive's element are destroyed. + * You should take this into consideration and make sure to always cancel the interval at the + * appropriate moment. See the example below for more details on how and when to do this. + *
* * @param {function()} fn A function that should be called repeatedly. * @param {number} delay Number of milliseconds between each function call. @@ -52,20 +60,27 @@ function $IntervalProvider() { $scope.blood_1 = $scope.blood_1 - 3; $scope.blood_2 = $scope.blood_2 - 4; } else { - $interval.cancel(stop); + $scope.stopFight(); } }, 100); }; $scope.stopFight = function() { - $interval.cancel(stop); - stop = undefined; + if (angular.isDefined(stop)) { + $interval.cancel(stop); + stop = undefined; + } }; $scope.resetFight = function() { $scope.blood_1 = 100; $scope.blood_2 = 120; } + + $scope.$on('$destroy', function() { + // Make sure that the interval is destroyed too + $scope.stopFight(); + }); } angular.module('time', []) -- cgit v1.2.3