diff --git a/src/ngRoute/directive/ngView.js b/src/ngRoute/directive/ngView.js index 00e047cad698..a8a136df7c57 100644 --- a/src/ngRoute/directive/ngView.js +++ b/src/ngRoute/directive/ngView.js @@ -177,6 +177,7 @@ function ngViewFactory( $route, $anchorScroll, $compile, $controller, return function(scope, $element, attr) { var currentScope, currentElement, + autoScrollExp = attr.autoscroll, onloadExp = attr.onload || ''; scope.$on('$routeChangeSuccess', update); @@ -201,7 +202,12 @@ function ngViewFactory( $route, $anchorScroll, $compile, $controller, var newScope = scope.$new(); linker(newScope, function(clone) { clone.html(template); - $animate.enter(clone, null, currentElement || $element); + $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () { + if (angular.isDefined(autoScrollExp) + && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }); cleanupLastView(); @@ -224,9 +230,6 @@ function ngViewFactory( $route, $anchorScroll, $compile, $controller, link(currentScope); currentScope.$emit('$viewContentLoaded'); currentScope.$eval(onloadExp); - - // $anchorScroll might listen on event... - $anchorScroll(); }); } else { cleanupLastView(); diff --git a/test/ngRoute/directive/ngViewSpec.js b/test/ngRoute/directive/ngViewSpec.js index bfcb0929a10a..1df19d6a1cb2 100644 --- a/test/ngRoute/directive/ngViewSpec.js +++ b/test/ngRoute/directive/ngViewSpec.js @@ -698,4 +698,106 @@ describe('ngView animations', function() { } }); }); + + + describe('autoscroll', function () { + var autoScrollSpy; + + function spyOnAnchorScroll() { + return function($provide, $routeProvider) { + autoScrollSpy = jasmine.createSpy('$anchorScroll'); + $provide.value('$anchorScroll', autoScrollSpy); + $routeProvider.when('/foo', { + controller: angular.noop, + template: '
' + }); + }; + } + + function spyOnAnimateEnter() { + return function($animate) { + spyOn($animate, 'enter').andCallThrough(); + }; + } + + function compileAndLink(tpl) { + return function($compile, $rootScope, $location) { + element = $compile(tpl)($rootScope); + }; + } + + beforeEach(module(spyOnAnchorScroll(), 'mock.animate')); + beforeEach(inject(spyOnAnimateEnter())); + + it('should call $anchorScroll if autoscroll attribute is present', inject( + compileAndLink('
'), + function($rootScope, $animate, $timeout, $location) { + + $location.path('/foo'); + $rootScope.$digest(); + $animate.flushNext('enter'); + $timeout.flush(); + + expect(autoScrollSpy).toHaveBeenCalledOnce(); + })); + + + it('should call $anchorScroll if autoscroll evaluates to true', inject( + compileAndLink('
'), + function($rootScope, $animate, $timeout, $location) { + + $rootScope.value = true; + $location.path('/foo'); + $rootScope.$digest(); + $animate.flushNext('enter'); + $timeout.flush(); + + expect(autoScrollSpy).toHaveBeenCalledOnce(); + })); + + + it('should not call $anchorScroll if autoscroll attribute is not present', inject( + compileAndLink('
'), + function($rootScope, $location, $animate, $timeout) { + + $location.path('/foo'); + $rootScope.$digest(); + $animate.flushNext('enter'); + $timeout.flush(); + + expect(autoScrollSpy).not.toHaveBeenCalled(); + })); + + + it('should not call $anchorScroll if autoscroll evaluates to false', inject( + compileAndLink('
'), + function($rootScope, $location, $animate, $timeout) { + + $rootScope.value = false; + $location.path('/foo'); + $rootScope.$digest(); + $animate.flushNext('enter'); + $timeout.flush(); + + expect(autoScrollSpy).not.toHaveBeenCalled(); + })); + + + it('should only call $anchorScroll after the "enter" animation completes', inject( + compileAndLink('
'), + function($rootScope, $location, $animate, $timeout) { + $location.path('/foo'); + + expect($animate.enter).not.toHaveBeenCalled(); + $rootScope.$digest(); + + expect(autoScrollSpy).not.toHaveBeenCalled(); + + $animate.flushNext('enter'); + $timeout.flush(); + + expect($animate.enter).toHaveBeenCalledOnce(); + expect(autoScrollSpy).toHaveBeenCalledOnce(); + })); + }); });