I preciously asked on SO if it was possible to transclude the inner contents of a directive twice in the directive template (clone it and insert it in two places in the template).
A very helpful person helped me put this plunkr together.
http://plnkr.co/edit/k2UB1o4CTHtZ1voS0OKN?p=preview
It seems to work at first. The problem comes when I use any child element which uses transclusion itself. The error I get is...
[ngTransclude:orphan] Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element:
For example I have a button directive with the following definition.
angular.module('s4p.directives').directive('s4pButton', function () {
return {
restrict: 'E',
scope: {
icon: '@'
},
transclude: true,
replace: true,
template: getTemplate
};
function getTemplate(element, attr) {
var btnType = (typeof attr.type === 'undefined') ? 'button' : attr.type;
return '<button s4p-button type="' + btnType + '">'+
'<s4p-button-content ng-transclude></s4p-button-content>'+
'<s4p-button-icon ng-if="icon">'+
'<s4p-icon href="{{icon}}"></s4p-icon>'+
'</s4p-button-icon>'+
'</button>';
}
});
as soon as I put one of my buttons inside the tool bar and it tries to clone it I get the above error.
EDIT:
New PLUNKR with full example
http://plnkr.co/edit/uK8r4EA2IPRnYKfjWNVG?p=preview
Any help would be greatly appreciated.
Problem Code
The directive was trying to do the double transclusion in one invocation of the transclude function.
Correct Code
To transclude the directive contents into two places in the template, invoke the transclusion function twice.
If you need new scopes for the transclusion, you can create them with
scope.$new()
.For more information on creating new scopes, see AngularJS $rootScope.scope API Reference -- $new.
Using AngularJS jqLite
AngularJS jqLite is a tiny, API-compatible subset of jQuery that allows Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most commonly needed functionality with the goal of having a very small footprint.1
The
find
method of jqLite does not support attribute selectors. To make the above example compatible with jqLite, use custom tags for the transclusion targets.This way there is no need to add jQuery to the app as a dependency.