简体   繁体   中英

Detecting if optional transcluded elements are used in an AngularJS directive?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM