fix(ngInclude): Don't throw when the ngInclude element contains content with directives.

Related to #5069
This commit is contained in:
Tobias Bosch 2013-11-21 21:54:42 -08:00
parent 579242346c
commit 0a7cbb33b0
2 changed files with 51 additions and 14 deletions

View file

@ -188,18 +188,23 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
if (thisChangeId !== changeCounter) return;
var newScope = scope.$new();
$transclude(newScope, function(clone) {
cleanupLastIncludeContent();
// 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;
currentScope = newScope;
currentElement = clone;
currentElement.html(response);
$animate.enter(currentElement, null, $element, afterAnimation);
$compile(currentElement.contents())(currentScope);
currentScope.$emit('$includeContentLoaded');
scope.$eval(onloadExp);
});
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();
});

View file

@ -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,
@ -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() {