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

Commit d414b78

Browse files
petebacondarwinvojtajina
authored andcommitted
fix($compile): fix nested isolated transclude directives
Closes #1809 Closes #7499
1 parent ad0c510 commit d414b78

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

src/ng/compile.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
964964
// or
965965
// - there is no parentBoundTranscludeFn already and a transcludeFn was passed in
966966
if ( nodeLinkFn.transcludeOnThisElement || (!parentBoundTranscludeFn && transcludeFn) ) {
967-
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude || transcludeFn);
967+
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude || transcludeFn, parentBoundTranscludeFn);
968968
} else {
969969
childBoundTranscludeFn = parentBoundTranscludeFn;
970970
}
@@ -978,8 +978,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
978978
}
979979
}
980980

981-
function createBoundTranscludeFn(scope, transcludeFn) {
982-
return function boundTranscludeFn(transcludedScope, cloneFn, controllers) {
981+
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
982+
983+
// If there is a previous boundTransclude function and it has a transclusionScope then
984+
// use this instead of the current scope
985+
scope = previousBoundTranscludeFn && previousBoundTranscludeFn.transclusionScope || scope;
986+
987+
var boundTranscludeFn = function(transcludedScope, cloneFn, controllers) {
983988
var scopeCreated = false;
984989

985990
if (!transcludedScope) {
@@ -994,6 +999,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
994999
}
9951000
return clone;
9961001
};
1002+
1003+
// Store the transclusionScope for nested transclusions
1004+
boundTranscludeFn.transclusionScope = scope;
1005+
1006+
return boundTranscludeFn;
9971007
}
9981008

9991009
/**
@@ -1768,7 +1778,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17681778
safeAddClass(jqLite(linkNode), oldClasses);
17691779
}
17701780
if (afterTemplateNodeLinkFn.transclude) {
1771-
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
1781+
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
17721782
} else {
17731783
childBoundTranscludeFn = boundTranscludeFn;
17741784
}

test/ng/compileSpec.js

+67
Original file line numberDiff line numberDiff line change
@@ -4279,6 +4279,73 @@ describe('$compile', function() {
42794279
});
42804280

42814281

4282+
describe('nested isolated scope transcludes', function() {
4283+
beforeEach(module(function($compileProvider) {
4284+
4285+
$compileProvider.directive('trans', valueFn({
4286+
restrict: 'E',
4287+
template: '<div ng-transclude></div>',
4288+
transclude: true
4289+
}));
4290+
4291+
$compileProvider.directive('transAsync', valueFn({
4292+
restrict: 'E',
4293+
templateUrl: 'transAsync',
4294+
transclude: true
4295+
}));
4296+
4297+
$compileProvider.directive('iso', valueFn({
4298+
restrict: 'E',
4299+
transclude: true,
4300+
template: '<trans><span ng-transclude></span></trans>',
4301+
scope: {}
4302+
}));
4303+
$compileProvider.directive('isoAsync1', valueFn({
4304+
restrict: 'E',
4305+
transclude: true,
4306+
template: '<trans-async><span ng-transclude></span></trans-async>',
4307+
scope: {}
4308+
}));
4309+
$compileProvider.directive('isoAsync2', valueFn({
4310+
restrict: 'E',
4311+
transclude: true,
4312+
templateUrl: 'isoAsync',
4313+
scope: {}
4314+
}));
4315+
}));
4316+
4317+
beforeEach(inject(function($templateCache) {
4318+
$templateCache.put('transAsync', '<div ng-transclude></div>');
4319+
$templateCache.put('isoAsync', '<trans-async><span ng-transclude></span></trans-async>');
4320+
}));
4321+
4322+
4323+
it('should pass the outer scope to the transclude on the isolated template sync-sync', inject(function($compile, $rootScope) {
4324+
4325+
$rootScope.val = 'transcluded content';
4326+
element = $compile('<iso><span ng-bind="val"></span></iso>')($rootScope);
4327+
$rootScope.$digest();
4328+
expect(element.text()).toEqual('transcluded content');
4329+
}));
4330+
4331+
it('should pass the outer scope to the transclude on the isolated template async-sync', inject(function($compile, $rootScope) {
4332+
4333+
$rootScope.val = 'transcluded content';
4334+
element = $compile('<iso-async1><span ng-bind="val"></span></iso-async1>')($rootScope);
4335+
$rootScope.$digest();
4336+
expect(element.text()).toEqual('transcluded content');
4337+
}));
4338+
4339+
it('should pass the outer scope to the transclude on the isolated template async-async', inject(function($compile, $rootScope) {
4340+
4341+
$rootScope.val = 'transcluded content';
4342+
element = $compile('<iso-async2><span ng-bind="val"></span></iso-async2>')($rootScope);
4343+
$rootScope.$digest();
4344+
expect(element.text()).toEqual('transcluded content');
4345+
}));
4346+
4347+
});
4348+
42824349
describe('multiple siblings receiving transclusion', function() {
42834350

42844351
it("should only receive transclude from parent", function() {

0 commit comments

Comments
 (0)