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

Commit

Permalink
fix(ngView): only run anchorScroll after animation is done
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffbcross committed Nov 6, 2013
1 parent 6fb1915 commit da344da
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/ngRoute/directive/ngView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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();

Expand All @@ -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();
Expand Down
102 changes: 102 additions & 0 deletions test/ngRoute/directive/ngViewSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: '<div></div>'
});
};
}

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('<div><ng:view autoscroll></ng:view></div>'),
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('<div><ng:view src="tpl" autoscroll="value"></ng:view></div>'),
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('<div><ng:view></ng:view></div>'),
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('<div><ng:view autoscroll="value"></ng:view></div>'),
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('<div><ng:view autoscroll></ng:view></div>'),
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();
}));
});
});

0 comments on commit da344da

Please sign in to comment.