Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cefee8f

Browse files
committedMay 19, 2014
fix($compile): fix nested isolated transclude directives
Closes angular#1809 Closes angular#7499
1 parent 0dfbf8a commit cefee8f

File tree

2 files changed

+80
-4
lines changed

2 files changed

+80
-4
lines changed
 

‎src/ng/compile.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
969969
// or
970970
// - there is no boundTranscludeFn already and a transcludeFn was passed in
971971
if ( nodeLinkFn.transcludeOnThisElement || (!boundTranscludeFn && transcludeFn) ) {
972-
boundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude || transcludeFn);
972+
boundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude || transcludeFn, boundTranscludeFn);
973973
}
974974

975975
nodeLinkFn(childLinkFn, childScope, node, $rootElement, boundTranscludeFn);
@@ -981,8 +981,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
981981
}
982982
}
983983

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

988993
if (!transcludedScope) {
@@ -997,6 +1002,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
9971002
}
9981003
return clone;
9991004
};
1005+
1006+
// Store the transclusionScope for nested transclusions
1007+
boundTranscludeFn.transclusionScope = scope;
1008+
1009+
return boundTranscludeFn;
10001010
}
10011011

10021012
/**
@@ -1770,7 +1780,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17701780
safeAddClass(jqLite(linkNode), oldClasses);
17711781
}
17721782
if (afterTemplateNodeLinkFn.transclude) {
1773-
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
1783+
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
17741784
} else {
17751785
childBoundTranscludeFn = boundTranscludeFn;
17761786
}

‎test/ng/compileSpec.js

+66
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,72 @@ describe('$compile', function() {
15671567
}));
15681568
});
15691569

1570+
describe('nested isolated scope transcludes', function() {
1571+
beforeEach(module(function($compileProvider) {
1572+
1573+
$compileProvider.directive('trans', valueFn({
1574+
restrict: 'E',
1575+
template: '<div ng-transclude></div>',
1576+
transclude: true
1577+
}));
1578+
1579+
$compileProvider.directive('transAsync', valueFn({
1580+
restrict: 'E',
1581+
templateUrl: 'transAsync',
1582+
transclude: true
1583+
}));
1584+
1585+
$compileProvider.directive('iso', valueFn({
1586+
restrict: 'E',
1587+
transclude: true,
1588+
template: '<trans><span ng-transclude></span></trans>',
1589+
scope: {}
1590+
}));
1591+
$compileProvider.directive('isoAsync1', valueFn({
1592+
restrict: 'E',
1593+
transclude: true,
1594+
template: '<trans-async><span ng-transclude></span></trans-async>',
1595+
scope: {}
1596+
}));
1597+
$compileProvider.directive('isoAsync2', valueFn({
1598+
restrict: 'E',
1599+
transclude: true,
1600+
templateUrl: 'isoAsync',
1601+
scope: {}
1602+
}));
1603+
}));
1604+
1605+
beforeEach(inject(function($templateCache) {
1606+
$templateCache.put('transAsync', '<div ng-transclude></div>');
1607+
$templateCache.put('isoAsync', '<trans-async><span ng-transclude></span></trans-async>');
1608+
}));
1609+
1610+
1611+
it('should pass the outer scope to the transclude on the isolated template sync-sync', inject(function($compile, $rootScope) {
1612+
1613+
$rootScope.val = 'transcluded content';
1614+
element = $compile('<iso><span ng-bind="val"></span></iso>')($rootScope);
1615+
$rootScope.$digest();
1616+
expect(trim(element.text())).toEqual('transcluded content');
1617+
}));
1618+
1619+
it('should pass the outer scope to the transclude on the isolated template async-sync', inject(function($compile, $rootScope) {
1620+
1621+
$rootScope.val = 'transcluded content';
1622+
element = $compile('<iso-async1><span ng-bind="val"></span></iso-async1>')($rootScope);
1623+
$rootScope.$digest();
1624+
expect(trim(element.text())).toEqual('transcluded content');
1625+
}));
1626+
1627+
it('should pass the outer scope to the transclude on the isolated template async-async', inject(function($compile, $rootScope) {
1628+
1629+
$rootScope.val = 'transcluded content';
1630+
element = $compile('<iso-async2><span ng-bind="val"></span></iso-async2>')($rootScope);
1631+
$rootScope.$digest();
1632+
expect(trim(element.text())).toEqual('transcluded content');
1633+
}));
1634+
1635+
});
15701636

15711637

15721638
it("should fail if replacing and template doesn't have a single root element", function() {

0 commit comments

Comments
 (0)
Please sign in to comment.