From 7515df45b9461df6711d16be5b0cac14ed5cf633 Mon Sep 17 00:00:00 2001 From: Chris Chua Date: Mon, 23 Dec 2013 13:47:37 -0800 Subject: [PATCH] fix(carousel): cancel goNext on scope destruction Discovered after #1451 --- src/carousel/carousel.js | 6 ++++++ src/carousel/test/carousel.spec.js | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/carousel/carousel.js b/src/carousel/carousel.js index 854b3b6fe4..9314ae7512 100644 --- a/src/carousel/carousel.js +++ b/src/carousel/carousel.js @@ -14,6 +14,7 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition']) currentTimeout, isPlaying; self.currentSlide = null; + var destroyed = false; /* direction: "prev" or "next" */ self.select = function(nextSlide, direction) { var nextIndex = slides.indexOf(nextSlide); @@ -31,6 +32,8 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition']) } } function goNext() { + // Scope has been destroyed, stop here. + if (destroyed) { return; } //If we have a slide to transition from and we have a transition type and we're allowed, go if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) { //We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime @@ -66,6 +69,9 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition']) $scope.$currentTransition = null; } }; + $scope.$on('$destroy', function () { + destroyed = true; + }); /* Allow outside people to call indexOf on slides array */ self.indexOfSlide = function(slide) { diff --git a/src/carousel/test/carousel.spec.js b/src/carousel/test/carousel.spec.js index 78d41699c3..cdbfedcbe2 100644 --- a/src/carousel/test/carousel.spec.js +++ b/src/carousel/test/carousel.spec.js @@ -234,6 +234,19 @@ describe('carousel', function() { next.click(); testSlideActive(1); }); + + it('issue 1414 - should not continue running timers after scope is destroyed', function() { + testSlideActive(0); + $timeout.flush(); + testSlideActive(1); + $timeout.flush(); + testSlideActive(2); + $timeout.flush(); + testSlideActive(0); + scope.$destroy(); + expect($timeout.flush).toThrow('No deferred tasks to be flushed'); + }); + }); describe('controller', function() {