Skip to content

Commit

Permalink
fix($compile): do not bind twice transclude functions
Browse files Browse the repository at this point in the history
Do not double bind transclude functions that are passed to the compiler that were already bound

Worked with @dlongley on the implementation

Closes angular#9413
  • Loading branch information
lgalfaso committed Oct 13, 2014
1 parent 57ee249 commit 5425777
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {

function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn, elementTransclusion) {

// preserve previously bound scope
if (transcludeFn.$$bound) {
scope = transcludeFn.$$bound;
}

var boundTranscludeFn = function(transcludedScope, cloneFn, futureParentElement, controllers, containingScope) {

if (!transcludedScope) {
Expand All @@ -1327,6 +1332,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
return transcludeFn(transcludedScope, cloneFn, futureParentElement, controllers, previousBoundTranscludeFn);
};

boundTranscludeFn.$$bound = scope;

return boundTranscludeFn;
}

Expand Down Expand Up @@ -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 = {};
Expand Down Expand Up @@ -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;
Expand Down
73 changes: 73 additions & 0 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: '<div><div ng-if="foo"><div ng-transclude></div></div></div>',
compile: function(tElement, tAttrs) {
var content = tElement.contents();
tElement.empty();
return function(scope, element, attrs, ctrls, transcludeFn) {
element.append(content);
$compile(content, transcludeFn)(scope);
};
}
};
});
});
inject(function($compile) {
element = $compile(
'<div>' +
'<div ng-init="outer=true"></div>' +
'<div uses-transclude foo="foo">' +
'<div uses-transclude foo="foo">' +
'<span ng-if="outer">Success</span><span ng-if="!outer">Error</span>' +
'</div>' +
'</div>' +
'</div>')($rootScope);
$rootScope.foo = false;
$rootScope.$digest();
expect(countScopes($rootScope)).toBe(2);
expect(element.text()).toBe('');
$rootScope.foo = true;
$rootScope.$digest();
expect(countScopes($rootScope)).toBe(8);
expect(element.text()).toBe('Success');
$rootScope.foo = false;
$rootScope.$digest();
expect(countScopes($rootScope)).toBe(2);
expect(element.text()).toBe('');
$rootScope.foo = true;
$rootScope.$digest();
expect(countScopes($rootScope)).toBe(8);
expect(element.text()).toBe('Success');
});
});


// see issue https://github.com/angular/angular.js/issues/9095
describe('removing a transcluded element', function() {

Expand Down

0 comments on commit 5425777

Please sign in to comment.