diff --git a/src/ng/compile.js b/src/ng/compile.js index 393ab6375a27..4be8ee82dc1d 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1486,6 +1486,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }); }; + var boundSlots = boundTranscludeFn.$$slots = createMap(); + for (var slotName in transcludeFn.$$slots) { + boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn); + } + return boundTranscludeFn; } @@ -1646,6 +1651,27 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { }; } + + function compileTemplate(eager, $templateNodes, parentTranscludeFn, terminalPriority, ignoreDirective, previousCompileContext) { + var defaultSlot = []; + var slots = createMap(); + forEach($templateNodes, function(node) { + var slotName = jqLite(node).attr('ng-transclude-slot'); + var slot = defaultSlot; + if (slotName) { + slot = slots[slotName] = (slots[slotName] || []); + } + slot.push(node); + }); + + var transcludeFn = compilationGenerator(eager, defaultSlot, parentTranscludeFn, terminalPriority, ignoreDirective, previousCompileContext); + forEach(Object.keys(slots), function(slotName) { + slots[slotName] = compilationGenerator(eager, slots[slotName], parentTranscludeFn, terminalPriority, ignoreDirective, previousCompileContext); + }); + transcludeFn.$$slots = slots; + return transcludeFn; + } + /** * A function generator that is used to support both eager and lazy compilation * linking function. @@ -1815,7 +1841,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { compileNode = $compileNode[0]; replaceWith(jqCollection, sliceArgs($template), compileNode); - childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority, + childTranscludeFn = compileTemplate(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, { // Don't pass in: // - controllerDirectives - otherwise we'll create duplicates controllers @@ -1829,7 +1855,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } else { $template = jqLite(jqLiteClone(compileNode)).contents(); $compileNode.empty(); // clear contents - childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn); + childTranscludeFn = compileTemplate(mightHaveMultipleTransclusionError, $template, transcludeFn); } } diff --git a/src/ng/directive/ngTransclude.js b/src/ng/directive/ngTransclude.js index 36201a69ab73..8c189d3c75ab 100644 --- a/src/ng/directive/ngTransclude.js +++ b/src/ng/directive/ngTransclude.js @@ -65,9 +65,20 @@ var ngTranscludeDirective = ngDirective({ startingTag($element)); } - $transclude(function(clone) { - $element.empty(); - $element.append(clone); - }); + if ($attrs.ngTransclude) { + $transclude = $transclude.$$boundTransclude.$$slots[$attrs.ngTransclude]; + if (!$transclude) return; + + $transclude(undefined, function(clone) { + $element.empty(); + $element.append(clone); + }); + } else { + + $transclude(function(clone) { + $element.empty(); + $element.append(clone); + }); + } } }); diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 54942dfdd1e7..e160d7c7dd51 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -7262,6 +7262,104 @@ describe('$compile', function() { }); + describe('multi-slot transclude', function() { + it('should only include elements without `ng-transclude-slot` attribute in default transclusion function', function() { + module(function() { + directive('trans', function() { + return { + transclude: true, + template: '
' + }; + }); + }); + inject(function($rootScope, $compile) { + element = $compile( + '