I have a directive set up in the style shown below; it allows for optional transcluded elements like the <dir-header>
and <dir-footer>
used in the example.
directive.js (partial)
module.directive('dir', function () {
return {
restrict: 'E',
templateUrl: 'path/template.html',
transclude: {
'header': '?dirHeader',
'footer': '?dirFooter'
},
link: function (scope, elem, attrs) {
// do something
}
};
});
template.html
<div ng-transclude="header">
<!-- Transcluded header will appear here -->
</div>
<div class="static-content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div ng-transclude="footer">
<!-- Transcluded footer will appear here -->
</div>
Usage
<dir>
<dir-header>My Header</dir-header>
<dir-footer>My Footer</dir-footer>
</dir>
Based on what I have here is there a way to detect if <dir-header>
is being used? Can I access the content passed into it—in this case the string "My header"
—from the link function?
Some background on what I've done so far:
I've seen a few discussions on this topic using the transclude: true
style rather than transclude: {}
. Based on suggestions found from that research I tried the following:
link: function (scope, elem, attrs, $transclude) {
$transclude(function (clone) {
console.log(clone);
});
}
I couldn't quite discern how clone works but it seems to be a NodeList representing what has been transcluded. Unfortunately the only piece of useful information I get from this is a length; clone.length
for my usage example above would be 3 (one for dir
, header
, and footer
). If I remove footer
the length would be 2, and so on. There doesn't seem to be any data to differentiate the elements in the NodeList, though, so I can't tell which transcluded elements are being used, just how many.
Ultimately I would like to set some style conditions based on whether a particular transcluded element is being used or not.
isSlotFilled
function on the transclude
function will give you the desired result.
angular.module('App', [])
.directive('dir', function () {
return {
restrict: 'E',
template: `
<div ng-transclude="header"></div>
<div class="static-content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div ng-transclude="footer">
`,
transclude: {
'header': '?dirHeader',
'footer': '?dirFooter'
},
link: function ($s, $el, $attrs, thisCtrl, $transclude) {
console.log($transclude.isSlotFilled('header'))
console.log($transclude.isSlotFilled('footer'))
}
};
});
working plnkr