From a6b9bd6e24b4cde71711d7b3686149d98d4be298 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Thu, 10 Apr 2014 23:23:04 +0300 Subject: [PATCH 1/2] fix(sortable): race condition when DOM changes inside a digest loop. --- bower.json | 2 +- package.json | 2 +- src/sortable.js | 25 ++++++++++++++----------- test/sortable.spec.js | 21 +++++++++++++++++++++ 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/bower.json b/bower.json index ff217fb..b8409e1 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-ui-sortable", - "version": "0.12.2", + "version": "0.12.3", "description": "This directive allows you to jQueryUI Sortable.", "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors", "license": "MIT", diff --git a/package.json b/package.json index 4ade395..c001a30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-ui-sortable", - "version": "0.12.2", + "version": "0.12.3", "description": "This directive allows you to jQueryUI Sortable.", "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors", "license": "MIT", diff --git a/src/sortable.js b/src/sortable.js index 786a776..714dfb3 100644 --- a/src/sortable.js +++ b/src/sortable.js @@ -174,18 +174,21 @@ angular.module('ui.sortable', []) }; scope.$watch(attrs.uiSortable, function(newVal /*, oldVal*/) { - angular.forEach(newVal, function(value, key) { - if(callbacks[key]) { - if( key === 'stop' ){ - // call apply after stop - value = combineCallbacks( - value, function() { scope.$apply(); }); + if (!!element.data('ui-sortable')) { + angular.forEach(newVal, function(value, key) { + if(callbacks[key]) { + if( key === 'stop' ){ + // call apply after stop + value = combineCallbacks( + value, function() { scope.$apply(); }); + } + // wrap the callback + value = combineCallbacks(callbacks[key], value); } - // wrap the callback - value = combineCallbacks(callbacks[key], value); - } - element.sortable('option', key, value); - }); + + element.sortable('option', key, value); + }); + } }, true); angular.forEach(callbacks, function(value, key) { diff --git a/test/sortable.spec.js b/test/sortable.spec.js index a29ef24..5127908 100644 --- a/test/sortable.spec.js +++ b/test/sortable.spec.js @@ -46,6 +46,27 @@ describe('uiSortable', function() { }); }); + it('should not try to apply options to a destroyed sortable', function() { + inject(function($compile, $rootScope, $timeout) { + var element; + var childScope = $rootScope.$new(); + element = $compile('
')(childScope); + $rootScope.$apply(function() { + childScope.items = ['One', 'Two', 'Three']; + childScope.opts = { + update: function() {} + }; + + element.remove(element.firstChild); + }); + + expect(function() { + $timeout.flush(); + }).not.toThrow(); + + }); + }); + }); }); From 36cceb54648f95a6243c48b93731c3409db60319 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Thu, 10 Apr 2014 23:23:39 +0300 Subject: [PATCH 2/2] Added missing descriptive comments. --- src/sortable.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sortable.js b/src/sortable.js index 714dfb3..b867916 100644 --- a/src/sortable.js +++ b/src/sortable.js @@ -42,6 +42,8 @@ angular.module('ui.sortable', []) scope.$watch(attrs.ngModel+'.length', function() { // Timeout to let ng-repeat modify the DOM $timeout(function() { + // ensure that the jquery-ui-sortable widget instance + // is still bound to the directive's element if (!!element.data('ui-sortable')) { element.sortable('refresh'); } @@ -174,6 +176,8 @@ angular.module('ui.sortable', []) }; scope.$watch(attrs.uiSortable, function(newVal /*, oldVal*/) { + // ensure that the jquery-ui-sortable widget instance + // is still bound to the directive's element if (!!element.data('ui-sortable')) { angular.forEach(newVal, function(value, key) { if(callbacks[key]) {