From 1b5bee4fa12b1f14e117f7ca222c2e2b64cc8558 Mon Sep 17 00:00:00 2001 From: Matias Niemelä Date: Fri, 2 Aug 2013 17:51:43 -0400 Subject: fix(ngInclude): ensure ngInclude is terminal and uses its own manual transclusion system --- src/ng/directive/ngInclude.js | 35 +++++++++++++++++++---------------- test/ng/directive/ngIncludeSpec.js | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js index 0f1f245c..e4484e81 100644 --- a/src/ng/directive/ngInclude.js +++ b/src/ng/directive/ngInclude.js @@ -149,18 +149,23 @@ * @description * Emitted every time the ngInclude content is reloaded. */ +var NG_INCLUDE_PRIORITY = 500; var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', '$animate', '$sce', function($http, $templateCache, $anchorScroll, $compile, $animate, $sce) { return { restrict: 'ECA', terminal: true, - transclude: 'element', - compile: function(element, attr, transclusion) { + priority: NG_INCLUDE_PRIORITY, + compile: function(element, attr) { var srcExp = attr.ngInclude || attr.src, onloadExp = attr.onload || '', autoScrollExp = attr.autoscroll; - return function(scope, $element) { + element.html(''); + var anchor = jqLite(document.createComment(' ngInclude: ' + srcExp + ' ')); + element.replaceWith(anchor); + + return function(scope) { var changeCounter = 0, currentScope, currentElement; @@ -184,23 +189,21 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile' if (thisChangeId !== changeCounter) return; var newScope = scope.$new(); - transclusion(newScope, function(clone) { - cleanupLastIncludeContent(); + cleanupLastIncludeContent(); - currentScope = newScope; - currentElement = clone; + currentScope = newScope; + currentElement = element.clone(); + currentElement.html(response); + $animate.enter(currentElement, null, anchor); - currentElement.html(response); - $animate.enter(currentElement, null, $element); - $compile(currentElement.contents())(currentScope); + $compile(currentElement, false, NG_INCLUDE_PRIORITY - 1)(currentScope); - if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { - $anchorScroll(); - } + if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } - currentScope.$emit('$includeContentLoaded'); - scope.$eval(onloadExp); - }); + currentScope.$emit('$includeContentLoaded'); + scope.$eval(onloadExp); }).error(function() { if (thisChangeId === changeCounter) cleanupLastIncludeContent(); }); diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js index f1bfbba2..b712c130 100644 --- a/test/ng/directive/ngIncludeSpec.js +++ b/test/ng/directive/ngIncludeSpec.js @@ -280,6 +280,31 @@ describe('ngInclude', function() { dealoc(element); })); + it('should compile only the inner content once', function() { + var log = []; + + module(function($compileProvider) { + $compileProvider.directive('compileLog', function() { + return { + compile: function() { + log.push('compile'); + } + }; + }); + }); + + inject(function($compile, $rootScope, $templateCache) { + $templateCache.put('tpl.html', [200, '
123
', {}]); + element = $compile('
')($rootScope); + + $rootScope.exp = 'tpl.html'; + $rootScope.$digest(); + + expect(element.text()).toBe('123'); + expect(log).toEqual(['compile']); + }); + }); + describe('autoscoll', function() { var autoScrollSpy; -- cgit v1.2.3