diff options
| author | Paulo Scardine | 2013-06-09 23:16:26 -0300 |
|---|---|---|
| committer | Pete Bacon Darwin | 2013-07-11 22:07:15 +0100 |
| commit | a4ec297925f052bf9ea1aba9f584eaaf7472fb93 (patch) | |
| tree | 8fe4cffef94120963fa19e445afd2a79fee197ad | |
| parent | 93d7e60d43c23c2c7658c3f3e0d500f325083702 (diff) | |
| download | angular.js-a4ec297925f052bf9ea1aba9f584eaaf7472fb93.tar.bz2 | |
fix(scope): watches can be safely unregistered inside watch handlers
Closes #2915
| -rw-r--r-- | src/ng/rootScope.js | 2 | ||||
| -rw-r--r-- | test/ng/rootScopeSpec.js | 24 |
2 files changed, 25 insertions, 1 deletions
diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js index 1025bbd7..733cec20 100644 --- a/src/ng/rootScope.js +++ b/src/ng/rootScope.js @@ -393,7 +393,7 @@ function $RootScopeProvider(){ watch = watchers[length]; // Most common watches are on primitives, in which case we can short // circuit it with === operator, only when === fails do we use .equals - if ((value = watch.get(current)) !== (last = watch.last) && + if (watch && (value = watch.get(current)) !== (last = watch.last) && !(watch.eq ? equals(value, last) : (typeof value == 'number' && typeof last == 'number' diff --git a/test/ng/rootScopeSpec.js b/test/ng/rootScopeSpec.js index 8031968a..27faf3e2 100644 --- a/test/ng/rootScopeSpec.js +++ b/test/ng/rootScopeSpec.js @@ -318,6 +318,30 @@ describe('Scope', function() { expect(listener).not.toHaveBeenCalled(); })); + it('should allow a watch to be unregistered while in a digest', inject(function($rootScope) { + var remove1, remove2; + $rootScope.$watch('remove', function() { + remove1(); + remove2(); + }); + remove1 = $rootScope.$watch('thing', function() {}); + remove2 = $rootScope.$watch('thing', function() {}); + expect(function() { + $rootScope.$apply('remove = true'); + }).not.toThrow(); + })); + + it('should allow a watch to be added while in a digest', inject(function($rootScope) { + var watch1 = jasmine.createSpy('watch1'), + watch2 = jasmine.createSpy('watch2'); + $rootScope.$watch('foo', function() { + $rootScope.$watch('foo', watch1); + $rootScope.$watch('foo', watch2); + }); + $rootScope.$apply('foo = true'); + expect(watch1).toHaveBeenCalled(); + expect(watch2).toHaveBeenCalled(); + })); it('should not infinitely digest when current value is NaN', inject(function($rootScope) { $rootScope.$watch(function() { return NaN;}); |
