fix($compile): fix nested isolated transclude directives

Closes #1809
Closes #7499
This commit is contained in:
Peter Bacon Darwin
2014-05-23 12:11:28 +01:00
committed by Vojta Jina
parent ad0c5107ba
commit d414b78717
2 changed files with 81 additions and 4 deletions

View File

@@ -964,7 +964,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
// or
// - there is no parentBoundTranscludeFn already and a transcludeFn was passed in
if ( nodeLinkFn.transcludeOnThisElement || (!parentBoundTranscludeFn && transcludeFn) ) {
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude || transcludeFn);
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude || transcludeFn, parentBoundTranscludeFn);
} else {
childBoundTranscludeFn = parentBoundTranscludeFn;
}
@@ -978,8 +978,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
}
function createBoundTranscludeFn(scope, transcludeFn) {
return function boundTranscludeFn(transcludedScope, cloneFn, controllers) {
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
// If there is a previous boundTransclude function and it has a transclusionScope then
// use this instead of the current scope
scope = previousBoundTranscludeFn && previousBoundTranscludeFn.transclusionScope || scope;
var boundTranscludeFn = function(transcludedScope, cloneFn, controllers) {
var scopeCreated = false;
if (!transcludedScope) {
@@ -994,6 +999,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
return clone;
};
// Store the transclusionScope for nested transclusions
boundTranscludeFn.transclusionScope = scope;
return boundTranscludeFn;
}
/**
@@ -1768,7 +1778,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
safeAddClass(jqLite(linkNode), oldClasses);
}
if (afterTemplateNodeLinkFn.transclude) {
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
} else {
childBoundTranscludeFn = boundTranscludeFn;
}

View File

@@ -4279,6 +4279,73 @@ describe('$compile', function() {
});
describe('nested isolated scope transcludes', function() {
beforeEach(module(function($compileProvider) {
$compileProvider.directive('trans', valueFn({
restrict: 'E',
template: '<div ng-transclude></div>',
transclude: true
}));
$compileProvider.directive('transAsync', valueFn({
restrict: 'E',
templateUrl: 'transAsync',
transclude: true
}));
$compileProvider.directive('iso', valueFn({
restrict: 'E',
transclude: true,
template: '<trans><span ng-transclude></span></trans>',
scope: {}
}));
$compileProvider.directive('isoAsync1', valueFn({
restrict: 'E',
transclude: true,
template: '<trans-async><span ng-transclude></span></trans-async>',
scope: {}
}));
$compileProvider.directive('isoAsync2', valueFn({
restrict: 'E',
transclude: true,
templateUrl: 'isoAsync',
scope: {}
}));
}));
beforeEach(inject(function($templateCache) {
$templateCache.put('transAsync', '<div ng-transclude></div>');
$templateCache.put('isoAsync', '<trans-async><span ng-transclude></span></trans-async>');
}));
it('should pass the outer scope to the transclude on the isolated template sync-sync', inject(function($compile, $rootScope) {
$rootScope.val = 'transcluded content';
element = $compile('<iso><span ng-bind="val"></span></iso>')($rootScope);
$rootScope.$digest();
expect(element.text()).toEqual('transcluded content');
}));
it('should pass the outer scope to the transclude on the isolated template async-sync', inject(function($compile, $rootScope) {
$rootScope.val = 'transcluded content';
element = $compile('<iso-async1><span ng-bind="val"></span></iso-async1>')($rootScope);
$rootScope.$digest();
expect(element.text()).toEqual('transcluded content');
}));
it('should pass the outer scope to the transclude on the isolated template async-async', inject(function($compile, $rootScope) {
$rootScope.val = 'transcluded content';
element = $compile('<iso-async2><span ng-bind="val"></span></iso-async2>')($rootScope);
$rootScope.$digest();
expect(element.text()).toEqual('transcluded content');
}));
});
describe('multiple siblings receiving transclusion', function() {
it("should only receive transclude from parent", function() {