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

Commit

Permalink
fix($compile): bound transclusion to correct scope
Browse files Browse the repository at this point in the history
Nested isolated transclude directives.

This improves/fixes the fix in d414b78.

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.
  • Loading branch information
vojtajina committed May 29, 2014
1 parent 0c8a2cd commit 56c6021
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 13 deletions.
15 changes: 4 additions & 11 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,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.
Expand All @@ -869,7 +869,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;
};
}
Expand Down Expand Up @@ -985,10 +985,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;

Expand All @@ -998,16 +994,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;
}

Expand Down Expand Up @@ -1786,7 +1779,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;
Expand Down
7 changes: 5 additions & 2 deletions test/ng/directive/ngIfSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,17 +204,20 @@ describe('ngIf and transcludes', function() {
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: '<div ng-if="true"><div ng-transclude></div></div>',
template: '<div ng-if="true">val={{val}}-<div ng-transclude></div></div>',
scope: {}
}));
});
inject(function($compile, $rootScope) {
$rootScope.val = 'transcluded content';
var element = $compile('<iso><span ng-bind="val"></span></iso>')($rootScope);
$rootScope.$digest();
expect(trim(element.text())).toEqual('transcluded content');
expect(trim(element.text())).toEqual('val=value in iso scope-transcluded content');
dealoc(element);
});
});
Expand Down

0 comments on commit 56c6021

Please sign in to comment.