From 90f87072e83234ae366cfeb3c281503c31dad738 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Thu, 14 Nov 2013 13:50:36 -0800 Subject: fix($compile): accessing controllers of transcluded directives from children Additional API (backwards compatible) - Injects `$transclude` (see directive controllers) as 5th argument to directive link functions. - `$transclude` takes an optional scope as first parameter that overrides the bound scope. Deprecations: - `transclude` parameter of directive compile functions (use the new parameter for link functions instead). Refactorings: - Don't use comment node to temporarily store controllers - `ngIf`, `ngRepeat`, ... now all use `$transclude` Closes #4935. --- src/ng/compile.js | 141 ++++++++++++++++++++++++++-------------- src/ng/directive/ngIf.js | 6 +- src/ng/directive/ngInclude.js | 6 +- src/ng/directive/ngRepeat.js | 6 +- src/ng/directive/ngSwitch.js | 16 ++--- src/ngRoute/directive/ngView.js | 6 +- 6 files changed, 110 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/ng/compile.js b/src/ng/compile.js index 039c211c..4d83f379 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -178,8 +178,9 @@ * * `$scope` - Current scope associated with the element * * `$element` - Current element * * `$attrs` - Current attributes object for the element - * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope: - * `function(cloneLinkingFn)`. + * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope. + * The scope can be overridden by an optional first argument. + * `function([scope], cloneLinkingFn)`. * * * #### `require` @@ -272,7 +273,7 @@ * * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared * between all directive compile functions. * - * * `transclude` - A transclude linking function: `function(scope, cloneLinkingFn)`. + * * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)` * *
- * function link(scope, iElement, iAttrs, controller) { ... }
+ * function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
*
*
* The link function is responsible for registering DOM listeners as well as updating the DOM. It is
@@ -316,6 +323,10 @@
* element defines a controller. The controller is shared among all the directives, which allows
* the directives to use the controllers as a communication channel.
*
+ * * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
+ * The scope can be overridden by an optional first argument. This is the same as the `$transclude`
+ * parameter of directive controllers.
+ * `function([scope], cloneLinkingFn)`.
*
*
* #### Pre-linking function
@@ -821,7 +832,7 @@ function $CompileProvider($provide) {
var compositeLinkFn =
compileNodes($compileNodes, transcludeFn, $compileNodes,
maxPriority, ignoreDirective, previousCompileContext);
- return function publicLinkFn(scope, cloneConnectFn){
+ return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){
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.
@@ -829,6 +840,10 @@ function $CompileProvider($provide) {
? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
: $compileNodes;
+ forEach(transcludeControllers, function(instance, name) {
+ $linkNode.data('$' + name + 'Controller', instance);
+ });
+
// Attach scope only to non-text nodes.
for(var i = 0, ii = $linkNode.length; i