diff --git a/src/ng/compile.js b/src/ng/compile.js index 8be86d729451..3889d26e6c51 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1153,7 +1153,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { maxPriority, ignoreDirective, previousCompileContext); compile.$$addScopeClass($compileNodes); var namespace = null; - return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement){ + return function publicLinkFn(scope, cloneConnectFn, futureParentElement, transcludeControllers, parentBoundTranscludeFn){ assertArg(scope, 'scope'); if (!namespace) { namespace = detectNamespaceForChildElements(futureParentElement); @@ -1317,16 +1317,23 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn, elementTransclusion) { - var boundTranscludeFn = function(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) { + // preserve previously bound scope + if (transcludeFn.$$bound) { + scope = transcludeFn.$$bound; + } + + var boundTranscludeFn = function(transcludedScope, cloneFn, futureParentElement, controllers, containingScope) { if (!transcludedScope) { transcludedScope = scope.$new(false, containingScope); transcludedScope.$$transcluded = true; } - return transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn, futureParentElement); + return transcludeFn(transcludedScope, cloneFn, futureParentElement, controllers, previousBoundTranscludeFn); }; + boundTranscludeFn.$$bound = scope; + return boundTranscludeFn; } @@ -1793,7 +1800,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { isolateScope = scope.$new(true); } - transcludeFn = boundTranscludeFn && controllersBoundTransclude; + if (boundTranscludeFn) { + transcludeFn = controllersBoundTransclude; + transcludeFn.$$bound = boundTranscludeFn.$$bound; + } if (controllerDirectives) { // TODO: merge `controllers` and `elementControllers` into single object. controllers = {}; @@ -1953,7 +1963,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { var transcludeControllers; // No scope passed in: - if (!isScope(scope)) { + if (!isScope(scope) && !isUndefined(scope)) { futureParentElement = cloneAttachFn; cloneAttachFn = scope; scope = undefined; @@ -1965,7 +1975,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { if (!futureParentElement) { futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element; } - return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild); + return boundTranscludeFn(scope, cloneAttachFn, futureParentElement, transcludeControllers, scopeToChild); } } } diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js index c6655c2d7082..ed7d0901ec0b 100644 --- a/src/ng/directive/ngInclude.js +++ b/src/ng/directive/ngInclude.js @@ -284,7 +284,7 @@ var ngIncludeFillContentDirective = ['$compile', $compile(jqLiteBuildFragment(ctrl.template, document).childNodes)(scope, function namespaceAdaptedClone(clone) { $element.append(clone); - }, undefined, undefined, $element); + }, $element); return; } diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 263768447f7e..64d0fcc55894 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -5124,6 +5124,79 @@ describe('$compile', function() { }); + it('should bind the tranclude function to the original scope when used ' + + 'in a future `$compile` call', function() { + + function countScopes($rootScope) { + return [$rootScope].concat( + getChildScopes($rootScope) + ).length; + } + + function getChildScopes(scope) { + var children = []; + if (!scope.$$childHead) { return children; } + var childScope = scope.$$childHead; + do { + children.push(childScope); + children = children.concat(getChildScopes(childScope)); + } while ((childScope = childScope.$$nextSibling)); + return children; + } + + + module(function() { + directive('isolate', function() { + return { + scope: {} + }; + }); + directive('usesTransclude', function($compile) { + return { + scope: {foo: '='}, + transclude: true, + template: '