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

Commit 1b5bee4

Browse files
matskomhevery
authored andcommitted
fix(ngInclude): ensure ngInclude is terminal and uses its own manual transclusion system
1 parent 45dc9ee commit 1b5bee4

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

src/ng/directive/ngInclude.js

+19-16
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,23 @@
149149
* @description
150150
* Emitted every time the ngInclude content is reloaded.
151151
*/
152+
var NG_INCLUDE_PRIORITY = 500;
152153
var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', '$animate', '$sce',
153154
function($http, $templateCache, $anchorScroll, $compile, $animate, $sce) {
154155
return {
155156
restrict: 'ECA',
156157
terminal: true,
157-
transclude: 'element',
158-
compile: function(element, attr, transclusion) {
158+
priority: NG_INCLUDE_PRIORITY,
159+
compile: function(element, attr) {
159160
var srcExp = attr.ngInclude || attr.src,
160161
onloadExp = attr.onload || '',
161162
autoScrollExp = attr.autoscroll;
162163

163-
return function(scope, $element) {
164+
element.html('');
165+
var anchor = jqLite(document.createComment(' ngInclude: ' + srcExp + ' '));
166+
element.replaceWith(anchor);
167+
168+
return function(scope) {
164169
var changeCounter = 0,
165170
currentScope,
166171
currentElement;
@@ -184,23 +189,21 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
184189
if (thisChangeId !== changeCounter) return;
185190
var newScope = scope.$new();
186191

187-
transclusion(newScope, function(clone) {
188-
cleanupLastIncludeContent();
192+
cleanupLastIncludeContent();
189193

190-
currentScope = newScope;
191-
currentElement = clone;
194+
currentScope = newScope;
195+
currentElement = element.clone();
196+
currentElement.html(response);
197+
$animate.enter(currentElement, null, anchor);
192198

193-
currentElement.html(response);
194-
$animate.enter(currentElement, null, $element);
195-
$compile(currentElement.contents())(currentScope);
199+
$compile(currentElement, false, NG_INCLUDE_PRIORITY - 1)(currentScope);
196200

197-
if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
198-
$anchorScroll();
199-
}
201+
if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
202+
$anchorScroll();
203+
}
200204

201-
currentScope.$emit('$includeContentLoaded');
202-
scope.$eval(onloadExp);
203-
});
205+
currentScope.$emit('$includeContentLoaded');
206+
scope.$eval(onloadExp);
204207
}).error(function() {
205208
if (thisChangeId === changeCounter) cleanupLastIncludeContent();
206209
});

test/ng/directive/ngIncludeSpec.js

+25
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,31 @@ describe('ngInclude', function() {
280280
dealoc(element);
281281
}));
282282

283+
it('should compile only the inner content once', function() {
284+
var log = [];
285+
286+
module(function($compileProvider) {
287+
$compileProvider.directive('compileLog', function() {
288+
return {
289+
compile: function() {
290+
log.push('compile');
291+
}
292+
};
293+
});
294+
});
295+
296+
inject(function($compile, $rootScope, $templateCache) {
297+
$templateCache.put('tpl.html', [200, '<div compile-log>123</div>', {}]);
298+
element = $compile('<div><div ng-include="exp"></div></div>')($rootScope);
299+
300+
$rootScope.exp = 'tpl.html';
301+
$rootScope.$digest();
302+
303+
expect(element.text()).toBe('123');
304+
expect(log).toEqual(['compile']);
305+
});
306+
});
307+
283308

284309
describe('autoscoll', function() {
285310
var autoScrollSpy;

0 commit comments

Comments
 (0)