Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 884ef0d

Browse files
committed
fix(Scope): don't let watch deregistration mess up the dirty-checking digest loop
Closes #5525
1 parent 010413f commit 884ef0d

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/ng/rootScope.js

+1
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ function $RootScopeProvider(){
353353

354354
return function() {
355355
arrayRemove(array, watcher);
356+
lastDirtyWatch = null;
356357
};
357358
},
358359

test/ng/rootScopeSpec.js

+47
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,53 @@ describe('Scope', function() {
405405
$rootScope.$apply('remove = true');
406406
}).not.toThrow();
407407
}));
408+
409+
410+
it('should not mess up the digest loop if deregistration happens during digest', inject(
411+
function($rootScope, log) {
412+
413+
// we are testing this due to regression #5525 which is related to how the digest loops lastDirtyWatch
414+
// short-circuiting optimization works
415+
416+
// scenario: watch1 deregistering watch1
417+
var scope = $rootScope.$new();
418+
var deregWatch1 = scope.$watch(log.fn('watch1'), function() { deregWatch1(); log('watchAction1'); });
419+
scope.$watch(log.fn('watch2'), log.fn('watchAction2'));
420+
scope.$watch(log.fn('watch3'), log.fn('watchAction3'));
421+
422+
$rootScope.$digest();
423+
424+
expect(log).toEqual(['watch1', 'watchAction1', 'watch2', 'watchAction2', 'watch3', 'watchAction3',
425+
'watch2', 'watch3']);
426+
scope.$destroy();
427+
log.reset();
428+
429+
430+
// scenario: watch1 deregistering watch2
431+
scope = $rootScope.$new();
432+
scope.$watch(log.fn('watch1'), function() { deregWatch2(); log('watchAction1'); });
433+
var deregWatch2 = scope.$watch(log.fn('watch2'), log.fn('watchAction2'));
434+
scope.$watch(log.fn('watch3'), log.fn('watchAction3'));
435+
436+
$rootScope.$digest();
437+
438+
expect(log).toEqual(['watch1', 'watchAction1', 'watch1', 'watch3', 'watchAction3',
439+
'watch1', 'watch3']);
440+
scope.$destroy();
441+
log.reset();
442+
443+
444+
// scenario: watch2 deregistering watch1
445+
scope = $rootScope.$new();
446+
deregWatch1 = scope.$watch(log.fn('watch1'), log.fn('watchAction1'));
447+
scope.$watch(log.fn('watch2'), function() { deregWatch1(); log('watchAction2'); });
448+
scope.$watch(log.fn('watch3'), log.fn('watchAction3'));
449+
450+
$rootScope.$digest();
451+
452+
expect(log).toEqual(['watch1', 'watchAction1', 'watch2', 'watchAction2', 'watch3', 'watchAction3',
453+
'watch2', 'watch3']);
454+
}));
408455
});
409456

410457

0 commit comments

Comments
 (0)