Skip to content

Commit 732ca80

Browse files
fix(ngInclude): only run anchorScroll after animation is done
We need to wait until animations have added the content to the document before trying to `autoscroll` to anchors that may have been inserted. Fixes angular#4723
1 parent 117de8e commit 732ca80

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

src/ng/directive/ngInclude.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
178178
};
179179

180180
scope.$watch($sce.parseAsResourceUrl(srcExp), function ngIncludeWatchAction(src) {
181+
var afterAnimation = function() {
182+
183+
if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
184+
$anchorScroll();
185+
}
186+
187+
};
181188
var thisChangeId = ++changeCounter;
182189

183190
if (src) {
@@ -192,13 +199,8 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
192199
currentElement = clone;
193200

194201
currentElement.html(response);
195-
$animate.enter(currentElement, null, $element);
202+
$animate.enter(currentElement, null, $element, afterAnimation);
196203
$compile(currentElement.contents())(currentScope);
197-
198-
if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
199-
$anchorScroll();
200-
}
201-
202204
currentScope.$emit('$includeContentLoaded');
203205
scope.$eval(onloadExp);
204206
});

test/ng/directive/ngIncludeSpec.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -322,22 +322,36 @@ describe('ngInclude', function() {
322322
};
323323
}
324324

325+
function spyOnAnimateEnter() {
326+
return function($animate) {
327+
spyOn($animate, 'enter').andCallThrough();
328+
};
329+
}
330+
331+
function runEnterAnimation($animate) {
332+
if ($animate.enter.mostRecentCall) {
333+
$animate.enter.mostRecentCall.args[3]();
334+
}
335+
}
336+
325337
function compileAndLink(tpl) {
326338
return function($compile, $rootScope) {
327339
element = $compile(tpl)($rootScope);
328340
};
329341
}
330342

331343
function changeTplAndValueTo(template, value) {
332-
return function($rootScope, $browser) {
344+
return function($rootScope, $browser, $animate) {
333345
$rootScope.$apply(function() {
334346
$rootScope.tpl = template;
335347
$rootScope.value = value;
336348
});
349+
runEnterAnimation($animate);
337350
};
338351
}
339352

340353
beforeEach(module(spyOnAnchorScroll()));
354+
beforeEach(inject(spyOnAnimateEnter()));
341355
beforeEach(inject(
342356
putIntoCache('template.html', 'CONTENT'),
343357
putIntoCache('another.html', 'CONTENT')));
@@ -374,6 +388,16 @@ describe('ngInclude', function() {
374388
changeTplAndValueTo('template.html', null), function() {
375389
expect(autoScrollSpy).not.toHaveBeenCalled();
376390
}));
391+
392+
it('should only call $anchorScroll after the "enter" animation completes', inject(
393+
compileAndLink('<div><ng:include src="tpl" autoscroll></ng:include></div>'),
394+
function($rootScope, $animate) {
395+
$rootScope.$apply("tpl = 'template.html'");
396+
expect($animate.enter).toHaveBeenCalledOnce();
397+
expect(autoScrollSpy).not.toHaveBeenCalled();
398+
runEnterAnimation($animate);
399+
expect(autoScrollSpy).toHaveBeenCalledOnce();
400+
}));
377401
});
378402
});
379403

0 commit comments

Comments
 (0)