I implemented a directive that includes several fragments of child content in a template. It works, but it seems simpler than most of the examples I've seen, and raised a few questions about how transcription works.
Here is the directive:
module.directive('myTransclude', function() { return { restrict: 'A', transclude: true, replace: true, scope: true, template: '<div style="border: 1px solid {{color}}"><div class="my-transclude-title"></div><div class="my-transclude-body"></div></div>', link: function(scope, element, attrs, controller, transclude) { // just to check transcluded scope scope.color = "red"; transclude(scope, function(clone, scope) { Array.prototype.forEach.call(clone, function(node) { if (! node.tagName) { return; } // look for a placeholder node in the template that matches the tag in the multi-transcluded content var placeholder = element[0].querySelector('.' + node.tagName.toLowerCase()); if (! placeholder) { return; } // insert the transcluded content placeholder.appendChild(node); }); }); } } });
and here is a usage example:
<div ng-controller="AppController"> <div my-transclude> <my-transclude-title> <strong ng-bind="title"></strong> </my-transclude-title> <my-transclude-body>My name is {{name}} and I've been transcluded!</my-transclude-body> </div> </div>
You can see it in action in this fiddle .
Pay attention to a few things:
- It maps fragments to template placeholders by element classes, rather than explicitly defined child directives. Is there any reason to do this anyway?
- Unlike many of the examples I saw, it clearly does not use the $ compilation service on child fragments. Angular seems to compile fragments after shutdown, at least in this simple case. Is it always right?
- It uses the (barely documented) argument transclude for the link function, and not another (barely documented) approach for embedding $ transclude local in the controller directive. Having heard so many warnings about not manipulating the DOM in controllers, the approach to the controller looks like an odd construct, and itβs more natural to handle this in the link functions. However, I tried it this way and it seems to work the same. Is there a difference between the two?
Thanks.
EDIT: partially answer the question No. 2, I found that you need to explicitly compile excluded content that is not cloned from the template in which the directive was applied. See the difference in behavior here: http://jsfiddle.net/4tSqr/3/
angularjs angularjs-directive
karlgold
source share