aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Scardine2013-06-09 23:16:26 -0300
committerPete Bacon Darwin2013-07-11 22:07:15 +0100
commita4ec297925f052bf9ea1aba9f584eaaf7472fb93 (patch)
tree8fe4cffef94120963fa19e445afd2a79fee197ad
parent93d7e60d43c23c2c7658c3f3e0d500f325083702 (diff)
downloadangular.js-a4ec297925f052bf9ea1aba9f584eaaf7472fb93.tar.bz2
fix(scope): watches can be safely unregistered inside watch handlers
Closes #2915
-rw-r--r--src/ng/rootScope.js2
-rw-r--r--test/ng/rootScopeSpec.js24
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;});