aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/AngularPublic.js4
-rw-r--r--src/ng/directive/ngInclude.js34
-rw-r--r--test/ng/directive/ngIncludeSpec.js40
3 files changed, 71 insertions, 7 deletions
diff --git a/src/AngularPublic.js b/src/AngularPublic.js
index d2c325c5..14fe25ae 100644
--- a/src/AngularPublic.js
+++ b/src/AngularPublic.js
@@ -28,6 +28,7 @@
ngHideDirective,
ngIfDirective,
ngIncludeDirective,
+ ngIncludeFillContentDirective,
ngInitDirective,
ngNonBindableDirective,
ngPluralizeDirective,
@@ -181,6 +182,9 @@ function publishExternalAPI(angular){
ngRequired: requiredDirective,
ngValue: ngValueDirective
}).
+ directive({
+ ngInclude: ngIncludeFillContentDirective
+ }).
directive(ngAttributeAliasDirectives).
directive(ngEventDirectives);
$provide.provider({
diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js
index b721aa23..d6b38663 100644
--- a/src/ng/directive/ngInclude.js
+++ b/src/ng/directive/ngInclude.js
@@ -147,13 +147,14 @@
* @description
* Emitted every time the ngInclude content is reloaded.
*/
-var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', '$animate', '$sce',
- function($http, $templateCache, $anchorScroll, $compile, $animate, $sce) {
+var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$animate', '$sce',
+ function($http, $templateCache, $anchorScroll, $animate, $sce) {
return {
restrict: 'ECA',
priority: 400,
terminal: true,
transclude: 'element',
+ controller: angular.noop,
compile: function(element, attr) {
var srcExp = attr.ngInclude || attr.src,
onloadExp = attr.onload || '',
@@ -187,6 +188,7 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
$http.get(src, {cache: $templateCache}).success(function(response) {
if (thisChangeId !== changeCounter) return;
var newScope = scope.$new();
+ ctrl.template = response;
// Note: This will also link all children of ng-include that were contained in the original
// html. If that content contains controllers, ... they could pollute/change the scope.
@@ -194,15 +196,14 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
// Note: We can't remove them in the cloneAttchFn of $transclude as that
// function is called before linking the content, which would apply child
// directives to non existing elements.
- var clone = $transclude(newScope, noop);
- cleanupLastIncludeContent();
+ var clone = $transclude(newScope, function(clone) {
+ cleanupLastIncludeContent();
+ $animate.enter(clone, null, $element, afterAnimation);
+ });
currentScope = newScope;
currentElement = clone;
- currentElement.html(response);
- $animate.enter(currentElement, null, $element, afterAnimation);
- $compile(currentElement.contents())(currentScope);
currentScope.$emit('$includeContentLoaded');
scope.$eval(onloadExp);
}).error(function() {
@@ -211,9 +212,28 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
scope.$emit('$includeContentRequested');
} else {
cleanupLastIncludeContent();
+ ctrl.template = null;
}
});
};
}
};
}];
+
+// This directive is called during the $transclude call of the first `ngInclude` directive.
+// It will replace and compile the content of the element with the loaded template.
+// We need this directive so that the element content is already filled when
+// the link function of another directive on the same element as ngInclude
+// is called.
+var ngIncludeFillContentDirective = ['$compile',
+ function($compile) {
+ return {
+ restrict: 'ECA',
+ priority: -400,
+ require: 'ngInclude',
+ link: function(scope, $element, $attr, ctrl) {
+ $element.html(ctrl.template);
+ $compile($element.contents())(scope);
+ }
+ };
+ }];
diff --git a/test/ng/directive/ngIncludeSpec.js b/test/ng/directive/ngIncludeSpec.js
index 2d115e8b..9e0a47b0 100644
--- a/test/ng/directive/ngIncludeSpec.js
+++ b/test/ng/directive/ngIncludeSpec.js
@@ -524,6 +524,46 @@ describe('ngInclude and transcludes', function() {
});
});
+
+ it('should link directives on the same element after the content has been loaded', function() {
+ var contentOnLink;
+ module(function() {
+ directive('test', function() {
+ return {
+ link: function(scope, element) {
+ contentOnLink = element.text();
+ }
+ };
+ });
+ });
+ inject(function($compile, $rootScope, $httpBackend) {
+ $httpBackend.expectGET('include.html').respond('someContent');
+ element = $compile('<div><div ng-include="\'include.html\'" test></div>')($rootScope);
+ $rootScope.$apply();
+ $httpBackend.flush();
+ expect(contentOnLink).toBe('someContent');
+ });
+ });
+
+ it('should add the content to the element before compiling it', function() {
+ var root;
+ module(function() {
+ directive('test', function() {
+ return {
+ link: function(scope, element) {
+ root = element.parent().parent();
+ }
+ };
+ });
+ });
+ inject(function($compile, $rootScope, $httpBackend) {
+ $httpBackend.expectGET('include.html').respond('<span test></span>');
+ element = $compile('<div><div ng-include="\'include.html\'"></div>')($rootScope);
+ $rootScope.$apply();
+ $httpBackend.flush();
+ expect(root[0]).toBe(element[0]);
+ });
+ });
});
describe('ngInclude animations', function() {