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

Commit

Permalink
fix(ngInclude): Don't throw when the ngInclude element contains conte…
Browse files Browse the repository at this point in the history
…nt with directives.

Related to #5069
  • Loading branch information
tbosch committed Nov 22, 2013
1 parent 5792423 commit 0a7cbb3
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
29 changes: 17 additions & 12 deletions src/ng/directive/ngInclude.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,23 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
if (thisChangeId !== changeCounter) return;
var newScope = scope.$new();

$transclude(newScope, function(clone) {
cleanupLastIncludeContent();

currentScope = newScope;
currentElement = clone;

currentElement.html(response);
$animate.enter(currentElement, null, $element, afterAnimation);
$compile(currentElement.contents())(currentScope);
currentScope.$emit('$includeContentLoaded');
scope.$eval(onloadExp);
});
// 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.
// However, using ng-include on an element with additional content does not make sense...
// 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();

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() {
if (thisChangeId === changeCounter) cleanupLastIncludeContent();
});
Expand Down
40 changes: 36 additions & 4 deletions test/ng/directive/ngIncludeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,22 @@ describe('ngInclude', function() {
});

describe('ngInclude and transcludes', function() {
var element, directive;

beforeEach(module(function($compileProvider) {
element = null;
directive = $compileProvider.directive;
}));

afterEach(function() {
if (element) {
dealoc(element);
}
});

it('should allow access to directive controller from children when used in a replace template', function() {
var controller;
module(function($compileProvider) {
var directive = $compileProvider.directive;
module(function() {
directive('template', valueFn({
template: '<div ng-include="\'include.html\'"></div>',
replace: true,
Expand All @@ -485,13 +497,33 @@ describe('ngInclude and transcludes', function() {
});
inject(function($compile, $rootScope, $httpBackend) {
$httpBackend.expectGET('include.html').respond('<div><div test></div></div>');
var element = $compile('<div><div template></div></div>')($rootScope);
element = $compile('<div><div template></div></div>')($rootScope);
$rootScope.$apply();
$httpBackend.flush();
expect(controller.flag).toBe(true);
dealoc(element);
});
});

it("should compile it's content correctly (although we remove it later)", function() {
var testElement;
module(function() {
directive('test', function() {
return {
link: function(scope, element) {
testElement = element;
}
};
});
});
inject(function($compile, $rootScope, $httpBackend) {
$httpBackend.expectGET('include.html').respond(' ');
element = $compile('<div><div ng-include="\'include.html\'"><div test></div></div></div>')($rootScope);
$rootScope.$apply();
$httpBackend.flush();
expect(testElement[0].nodeName).toBe('DIV');
});

});
});

describe('ngInclude animations', function() {
Expand Down

0 comments on commit 0a7cbb3

Please sign in to comment.