I'd like to transclude multiple pieces into one directive. Here is my idea of how I'd set it up.
<div id="content" class="mainDirective">
<div class="sub">
<ul>
<li>Everyone</li>
<li>Development (3)</li>
<li>Marketing</li>
</ul>
</div>
<div class="subButtons">
<span class="csStIcon add" data-ng-click="addTeam()"></span>
<span class="csStIcon edit" data-ng-click="editTeam()"></span>
<span class="csStIcon delete" data-ng-click="deleteTeam()"></span>
</div>
<div class="main">
<table>
<thead>
<tr><td>Name</td><td>Last name</td><td>Department</td></tr>
</thead>
<tbody>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
</tbody>
</table>
</div>
</div>
My directive template:
<div>
<div class="left">
<div data-ng-multi-transclude="sub"></div>
<div class="bottomOptions">
<span class="csStIcon collapse"></span>
<div data-ng-multi-transclude="subButtons"></div>
</div>
</div>
<div class="right">
<div data-ng-multi-transclude="main"></div>
</div>
</div>
And the final output:
<div>
<div class="left">
<div class="sub">
<ul>
<li>Everyone</li>
<li data-ng-click="loadDepartment()">Development (3)</li>
<li data-ng-click="loadDepartment()">Marketing</li>
</ul>
</div>
<div class="bottomOptions">
<span class="csStIcon collapse"></span>
<div class="subButtons">
<div class="subButtons">
<span class="csStIcon add" data-ng-click="addTeam()"></span>
<span class="csStIcon edit" data-ng-click="editTeam()"></span>
<span class="csStIcon delete" data-ng-click="deleteTeam()"></span>
</div>
</div>
</div>
</div>
<div class="right">
<div class="main">
<table>
<thead>
<tr><td>Name</td><td>Last name</td><td>Department</td></tr>
</thead>
<tbody>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
<tr><td>Lorem</td><td>Ipsum</td><td>Development</td></tr>
</tbody>
</table>
</div>
</div>
</div>
Is this possible within angular?
I ended up needing this functionality as well, so I wrote ng-multi-transclude -- funnily enough, I hadn't seen this question at the time, just lucked into the same name.
Usage is almost exactly as your question sketches; the only difference is that you use the name attribute to pick the "hole" to fill instead of the class attribute.
I came up with this directive using transclude function:
app.directive('mainDirective', function($compile) {
var template = ['<div>',
' <div class="left">',
' <div data-ng-multi-transclude="sub"></div>',
' <div class="bottomOptions">',
' <span class="csStIcon collapse"></span>',
' <div data-ng-multi-transclude="subButtons"></div>',
' </div>',
' </div>',
' <div class="right">',
' <div data-ng-multi-transclude="main"></div>',
' </div>',
'</div>'].join('\n');
return {
restrict: 'C',
transclude: true,
template: template,
link: function(scope, element, attr, model, transclude) {
var places = element.find('[data-ng-multi-transclude]');
console.log(element);
places.each(function() {
var self = $(this);
var class_ = self.data('ng-multi-transclude');
transclude(scope.$new(), function(clone, scope) {
var item = clone.closest('.' + class_);
$compile(item)(scope).appendTo(self);
});
});
}
};
});
I've used compile so you can use angular inside your transcluded code.
If you use this:
self.replaceWith($compile(item)(scope));
you'll don't get those original wrappers divs with data-ng-multi-transclude attributes.
Also you need to have jQuery included (always before Angular, because otherwise you get jQLite instead).
I have used multiple 'transclusions' in the component I am writing. In practice, it's just nested directives but they get the job done: https://github.com/AlexCppns/ac-fancy-input
More specifically, have a look at the following file:
https://github.com/AlexCppns/ac-fancy-input/blob/master/src/ac-fancy-input/directives/fancy-input.js