From 1382d4e88ec486b7749e45e6ccc864b3ec388cfe Mon Sep 17 00:00:00 2001 From: Vojta Jina Date: Tue, 27 May 2014 15:11:45 -0700 Subject: [PATCH] fix($compile): bound transclusion to correct scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nested isolated transclude directives. This improves/fixes the fix in d414b787173643362c0c513a1929d8e715ca340e. See the changed ng-ifunit test: The template inside ng-if should be bound to the isolate scope of `iso` directive (resp. its child scope). Not to a child of the root scope. This shows the issue with ng-if. It’s however problem with other directives too. Instead of remembering the scope, we pass around the bound parent transclusion. Conflicts: test/ng/directive/ngIfSpec.js --- src/ng/compile.js | 15 ++++----------- test/ng/directive/ngIfSpec.js | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 639b220ba959..d82a11f5c044 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -830,7 +830,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); safeAddClass($compileNodes, 'ng-scope'); - return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){ + return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn){ assertArg(scope, 'scope'); // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart // and sometimes changes the structure of the DOM. @@ -852,7 +852,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } if (cloneConnectFn) cloneConnectFn($linkNode, scope); - if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode); + if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn); return $linkNode; }; } @@ -968,10 +968,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { 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; @@ -981,16 +977,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { scopeCreated = true; } - var clone = transcludeFn(transcludedScope, cloneFn, controllers); + var clone = transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn); if (scopeCreated) { clone.on('$destroy', function() { transcludedScope.$destroy(); }); } return clone; }; - // Store the transclusionScope for nested transclusions - boundTranscludeFn.transclusionScope = scope; - return boundTranscludeFn; } @@ -1767,7 +1760,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // Copy in CSS classes from original node safeAddClass(jqLite(linkNode), oldClasses); } - if (afterTemplateNodeLinkFn.transclude) { + if (afterTemplateNodeLinkFn.transcludeOnThisElement) { childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn); } else { childBoundTranscludeFn = boundTranscludeFn; diff --git a/test/ng/directive/ngIfSpec.js b/test/ng/directive/ngIfSpec.js index 771e264a9a73..c4c253cca893 100755 --- a/test/ng/directive/ngIfSpec.js +++ b/test/ng/directive/ngIfSpec.js @@ -199,6 +199,28 @@ describe('ngIf and transcludes', function() { dealoc(element); }); }); + + + it('should use the correct transcluded scope', function() { + module(function($compileProvider) { + $compileProvider.directive('iso', valueFn({ + link: function(scope) { + scope.val = 'value in iso scope'; + }, + restrict: 'E', + transclude: true, + template: '
val={{val}}-
', + scope: {} + })); + }); + inject(function($compile, $rootScope) { + $rootScope.val = 'transcluded content'; + var element = $compile('')($rootScope); + $rootScope.$digest(); + expect(trim(element.text())).toEqual('val=value in iso scope-transcluded content'); + dealoc(element); + }); + }); }); describe('ngIf animations', function () {