检测是否在 AngularJS 指令中使用了可选的嵌入元素?

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

我有一个指令设置如下所示;它允许可选的嵌入元素,例如示例中使用的 <dir-header><dir-footer>

directive.js(部分)

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>

用法

<dir>
    <dir-header>My Header</dir-header>
    <dir-footer>My Footer</dir-footer>
</dir>

根据我这里有什么方法可以检测是否正在使用 <dir-header>?我能否从 link 函数访问传递给它的内容——在本例中为字符串 "My header"


到目前为止我所做的一些背景:

我看到一些关于此主题的讨论使用 transclude: true 风格而不是 transclude: {}。根据从该研究中发现的建议,我尝试了以下方法:

link: function (scope, elem, attrs, $transclude) {
    $transclude(function (clone) {
        console.log(clone);
    });
}

我不太清楚克隆是如何工作的,但它似乎是一个表示已被嵌入的内容的 NodeList。不幸的是,我从中得到的唯一有用信息是长度;对于我上面的用法示例,clone.length 将是 3(一个用于 dirheaderfooter)。如果我删除 footer 长度将为 2,依此类推。不过,似乎没有任何数据可以区分 NodeList 中的元素,所以我无法判断正在使用哪些被嵌入的元素,以及有多少。

最后我想根据是否使用特定的嵌入元素来设置一些样式条件。

isSlotFilled 函数加 transclude 函数会给你想要的结果。

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'))
        }
    };
  });

工作plnkr