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

Commit f595f13

Browse files
committed
fix($compile): do not double bound transclude functions
Do not double bind transclude functions that are passed to the compiler that were already bound Closes #9413
1 parent b6f4d4b commit f595f13

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

src/ng/compile.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
11531153
maxPriority, ignoreDirective, previousCompileContext);
11541154
compile.$$addScopeClass($compileNodes);
11551155
var namespace = null;
1156-
return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement){
1156+
return function publicLinkFn(scope, cloneConnectFn, futureParentElement, transcludeControllers, parentBoundTranscludeFn){
11571157
assertArg(scope, 'scope');
11581158
if (!namespace) {
11591159
namespace = detectNamespaceForChildElements(futureParentElement);
@@ -1317,14 +1317,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13171317

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

1320-
var boundTranscludeFn = function(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
1320+
var boundTranscludeFn = function(transcludedScope, cloneFn, futureParentElement, controllers, containingScope) {
13211321

1322-
if (!transcludedScope) {
1322+
if (!transcludedScope && !transcludeFn.$$bound) {
13231323
transcludedScope = scope.$new(false, containingScope);
13241324
transcludedScope.$$transcluded = true;
13251325
}
13261326

1327-
return transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn, futureParentElement);
1327+
return transcludeFn(transcludedScope, cloneFn, futureParentElement, controllers, previousBoundTranscludeFn);
13281328
};
13291329

13301330
return boundTranscludeFn;
@@ -1793,7 +1793,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17931793
isolateScope = scope.$new(true);
17941794
}
17951795

1796-
transcludeFn = boundTranscludeFn && controllersBoundTransclude;
1796+
if (boundTranscludeFn) {
1797+
transcludeFn = controllersBoundTransclude;
1798+
transcludeFn.$$bound = true;
1799+
}
17971800
if (controllerDirectives) {
17981801
// TODO: merge `controllers` and `elementControllers` into single object.
17991802
controllers = {};
@@ -1953,7 +1956,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19531956
var transcludeControllers;
19541957

19551958
// No scope passed in:
1956-
if (!isScope(scope)) {
1959+
if (!isScope(scope) && !isUndefined(scope)) {
19571960
futureParentElement = cloneAttachFn;
19581961
cloneAttachFn = scope;
19591962
scope = undefined;
@@ -1965,7 +1968,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19651968
if (!futureParentElement) {
19661969
futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
19671970
}
1968-
return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
1971+
return boundTranscludeFn(scope, cloneAttachFn, futureParentElement, transcludeControllers, scopeToChild);
19691972
}
19701973
}
19711974
}

src/ng/directive/ngInclude.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ var ngIncludeFillContentDirective = ['$compile',
284284
$compile(jqLiteBuildFragment(ctrl.template, document).childNodes)(scope,
285285
function namespaceAdaptedClone(clone) {
286286
$element.append(clone);
287-
}, undefined, undefined, $element);
287+
}, $element);
288288
return;
289289
}
290290

test/ng/compileSpec.js

+33
Original file line numberDiff line numberDiff line change
@@ -5124,6 +5124,39 @@ describe('$compile', function() {
51245124
});
51255125

51265126

5127+
it('should bind the tranclude function to the original scope when used ' +
5128+
'in a future `$compile` call', function() {
5129+
module(function() {
5130+
directive('usesTransclude', function($compile) {
5131+
return {
5132+
scope: {},
5133+
transclude: true,
5134+
template: '<div><div ng-transclude></div></div>',
5135+
compile: function(tElement, tAttrs) {
5136+
var content = tElement.contents();
5137+
tElement.empty();
5138+
return function(scope, element, attrs, ctrls, transcludeFn) {
5139+
element.append(content);
5140+
$compile(content, transcludeFn)(scope);
5141+
};
5142+
}
5143+
};
5144+
});
5145+
});
5146+
inject(function($compile) {
5147+
element = $compile(
5148+
'<div>' +
5149+
'<div ng-init="outer=true"></div>' +
5150+
'<div uses-transclude>' +
5151+
'<span ng-if="outer">Success</span><span ng-if="!outer">Error</span>' +
5152+
'</div>' +
5153+
'</div>')($rootScope);
5154+
$rootScope.$digest();
5155+
expect(element.text()).toBe('Success');
5156+
});
5157+
});
5158+
5159+
51275160
// see issue https://github.com/angular/angular.js/issues/9095
51285161
describe('removing a transcluded element', function() {
51295162

0 commit comments

Comments
 (0)