From 4257f8cd6191f644791bef75b89bdd43d8887a5a Mon Sep 17 00:00:00 2001 From: Wesley Cho Date: Fri, 15 Jan 2016 17:03:58 -0800 Subject: [PATCH] fix(paging): garbage collect parent $watchers - Garbage collect parent $watchers on $destroy --- src/pagination/pagination.js | 4 ++-- src/paging/paging.js | 11 +++++++++-- src/paging/test/paging.spec.js | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/pagination/pagination.js b/src/pagination/pagination.js index c67e370429..f51b5eefe7 100644 --- a/src/pagination/pagination.js +++ b/src/pagination/pagination.js @@ -12,10 +12,10 @@ angular.module('ui.bootstrap.pagination', ['ui.bootstrap.paging']) uibPaging.create(this, $scope, $attrs); if ($attrs.maxSize) { - $scope.$parent.$watch($parse($attrs.maxSize), function(value) { + ctrl._watchers.push($scope.$parent.$watch($parse($attrs.maxSize), function(value) { maxSize = parseInt(value, 10); ctrl.render(); - }); + })); } // Create page object used in template diff --git a/src/paging/paging.js b/src/paging/paging.js index 7adc5ddb73..1a18154a17 100644 --- a/src/paging/paging.js +++ b/src/paging/paging.js @@ -8,6 +8,7 @@ angular.module('ui.bootstrap.paging', []) create: function(ctrl, $scope, $attrs) { ctrl.setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop; ctrl.ngModelCtrl = { $setViewValue: angular.noop }; // nullModelCtrl + ctrl._watchers = []; ctrl.init = function(ngModelCtrl, config) { ctrl.ngModelCtrl = ngModelCtrl; @@ -18,11 +19,11 @@ angular.module('ui.bootstrap.paging', []) }; if ($attrs.itemsPerPage) { - $scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) { + ctrl._watchers.push($scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) { ctrl.itemsPerPage = parseInt(value, 10); $scope.totalPages = ctrl.calculateTotalPages(); ctrl.updatePage(); - }); + })); } else { ctrl.itemsPerPage = config.itemsPerPage; } @@ -80,6 +81,12 @@ angular.module('ui.bootstrap.paging', []) ctrl.ngModelCtrl.$render(); } }; + + $scope.$on('$destroy', function() { + while (ctrl._watchers.length) { + ctrl._watchers.shift()(); + } + }); } }; }]); diff --git a/src/paging/test/paging.spec.js b/src/paging/test/paging.spec.js index 652cd02b7e..6bafd4518a 100644 --- a/src/paging/test/paging.spec.js +++ b/src/paging/test/paging.spec.js @@ -253,4 +253,18 @@ describe('paging factory', function() { expect(ctrl.ngModelCtrl.$render).toHaveBeenCalled(); }); }); + + describe('gc', function() { + it('should clear watchers', function() { + var watcher1 = jasmine.createSpy('watcher1'), + watcher2 = jasmine.createSpy('watcher2'); + ctrl._watchers = [watcher1, watcher2]; + + $scope.$destroy(); + + expect(ctrl._watchers.length).toBe(0); + expect(watcher1).toHaveBeenCalled(); + expect(watcher2).toHaveBeenCalled(); + }); + }); });