Skip to content

Commit 297c887

Browse files
committed
Requiring Controllers from Transcluded Directives
1 parent f86edbd commit 297c887

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

src/compile.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ function $CompileProvider($provide) {
167167
return function publicLinkFn(scope, cloneAttachFn, options) {
168168
options = options || {};
169169
var parentBoundTranscludeFn = options.parentBoundTranscludeFn;
170+
var transcludeControllers = options.transcludeControllers;
170171
if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {
171172
parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;
172173
}
@@ -177,6 +178,9 @@ function $CompileProvider($provide) {
177178
} else {
178179
$linkNodes = $compileNodes;
179180
}
181+
_.forEach(transcludeControllers, function(controller, name) {
182+
$linkNodes.data('$' + name + 'Controller', controller.instance);
183+
});
180184
$linkNodes.data('$scope', scope);
181185
compositeLinkFn(scope, $linkNodes, parentBoundTranscludeFn);
182186
return $linkNodes;
@@ -229,11 +233,13 @@ function $CompileProvider($provide) {
229233

230234
var boundTranscludeFn;
231235
if (linkFn.nodeLinkFn.transcludeOnThisElement) {
232-
boundTranscludeFn = function(transcludedScope, cloneAttachFn, containingScope) {
236+
boundTranscludeFn = function(transcludedScope, cloneAttachFn, transcludeControllers, containingScope) {
233237
if (!transcludedScope) {
234238
transcludedScope = scope.$new(false, containingScope);
235239
}
236-
return linkFn.nodeLinkFn.transclude(transcludedScope, cloneAttachFn);
240+
return linkFn.nodeLinkFn.transclude(transcludedScope, cloneAttachFn, {
241+
transcludeControllers: transcludeControllers
242+
});
237243
};
238244
} else if (parentBoundTranscludeFn) {
239245
boundTranscludeFn = parentBoundTranscludeFn;
@@ -403,6 +409,7 @@ function $CompileProvider($provide) {
403409
var controllerDirectives = previousCompileContext.controllerDirectives;
404410
var childTranscludeFn;
405411
var hasTranscludeDirective = previousCompileContext.hasTranscludeDirective;
412+
var hasElementTranscludeDirective;
406413

407414
function getControllers(require, $element) {
408415
if (_.isArray(require)) {
@@ -490,6 +497,7 @@ function $CompileProvider($provide) {
490497
}
491498
hasTranscludeDirective = true;
492499
if (directive.transclude === 'element') {
500+
hasElementTranscludeDirective = true;
493501
var $originalCompileNode = $compileNode;
494502
$compileNode = attrs.$$element = $(document.createComment(' ' + directive.name + ': ' + attrs[directive.name] + ' '));
495503
$originalCompileNode.replaceWith($compileNode);
@@ -631,11 +639,15 @@ function $CompileProvider($provide) {
631639
});
632640

633641
function scopeBoundTranscludeFn(transcludedScope, cloneAttachFn) {
642+
var transcludeControllers;
634643
if (!transcludedScope || !transcludedScope.$watch || !transcludedScope.$evalAsync) {
635644
cloneAttachFn = transcludedScope;
636645
transcludedScope = undefined;
637646
}
638-
return boundTranscludeFn(transcludedScope, cloneAttachFn, scope);
647+
if (hasElementTranscludeDirective) {
648+
transcludeControllers = controllers;
649+
}
650+
return boundTranscludeFn(transcludedScope, cloneAttachFn, transcludeControllers, scope);
639651
}
640652
scopeBoundTranscludeFn.$$boundTransclude = boundTranscludeFn;
641653

test/compile_spec.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3470,6 +3470,40 @@ describe('$compile', function() {
34703470
});
34713471
});
34723472

3473+
it('supports requiring controllers', function() {
3474+
var MyController = function() { };
3475+
var gotCtrl;
3476+
var injector = makeInjectorWithDirectives({
3477+
myCtrlDirective: function() {
3478+
return {controller: MyController};
3479+
},
3480+
myTranscluder: function() {
3481+
return {
3482+
transclude: 'element',
3483+
link: function(scope, el, attrs, ctrl, transclude) {
3484+
el.after(transclude());
3485+
}
3486+
};
3487+
},
3488+
myOtherDirective: function() {
3489+
return {
3490+
require: '^myCtrlDirective',
3491+
link: function(scope, el, attrs, ctrl, transclude) {
3492+
gotCtrl = ctrl;
3493+
}
3494+
};
3495+
}
3496+
});
3497+
injector.invoke(function($compile, $rootScope) {
3498+
var el = $('<div><div my-ctrl-directive my-transcluder><div my-other-directive>Hello</div></div>');
3499+
3500+
$compile(el)($rootScope);
3501+
3502+
expect(gotCtrl).toBeDefined();
3503+
expect(gotCtrl instanceof MyController).toBe(true);
3504+
});
3505+
});
3506+
34733507
});
34743508

34753509
});

0 commit comments

Comments
 (0)