diff --git a/src/ng/directive/ngEventDirs.js b/src/ng/directive/ngEventDirs.js index c14b173a2b48..75edf369efd6 100644 --- a/src/ng/directive/ngEventDirs.js +++ b/src/ng/directive/ngEventDirs.js @@ -63,10 +63,12 @@ forEach( var callback = function() { fn(scope, {$event:event}); }; - if (forceAsyncEvents[eventName] && $rootScope.$$phase) { + if (!$rootScope.$$phase) { + scope.$apply(callback); + } else if (forceAsyncEvents[eventName]) { scope.$evalAsync(callback); } else { - scope.$apply(callback); + callback(); } }); }; diff --git a/test/ng/directive/ngEventDirsSpec.js b/test/ng/directive/ngEventDirsSpec.js index e2c2745f840e..df85fd902cd1 100644 --- a/test/ng/directive/ngEventDirsSpec.js +++ b/test/ng/directive/ngEventDirsSpec.js @@ -150,4 +150,46 @@ describe('event directives', function() { })); }); + + describe('click', function() { + + it('should call the listener synchronously if inside of $apply', + inject(function($rootScope, $compile) { + var watchedVal; + + element = $compile('')($rootScope); + $rootScope.$watch('value', function(newValue) { + watchedVal = newValue; + }); + $rootScope.click = jasmine.createSpy('click').and.callFake(function() { + $rootScope.value = 'newValue'; + }); + + $rootScope.$apply(function() { + element.triggerHandler('click'); + }); + + expect($rootScope.click).toHaveBeenCalledOnce(); + expect(watchedVal).toEqual('newValue'); + })); + + it('should call the listener synchronously if outside of $apply', + inject(function($rootScope, $compile) { + var watchedVal; + + element = $compile('')($rootScope); + $rootScope.$watch('value', function(newValue) { + watchedVal = newValue; + }); + $rootScope.click = jasmine.createSpy('click').and.callFake(function() { + $rootScope.value = 'newValue'; + }); + + element.triggerHandler('click'); + + expect($rootScope.click).toHaveBeenCalledOnce(); + expect(watchedVal).toEqual('newValue'); + })); + + }); });