Search code examples
javascriptangularjsangularjs-directiveangularjs-ng-transclude

In a named transclude slot, how do I transclude *only* the element's contents?


I've got a basic directive that I want to use transclusion. The relevant options are set up as follows:

restrict: "E",
replace: true,
transclude: {
  'toolbar': 'toolbarSlot'
},
scope: {
  pageTitle: "@"
},
templateUrl: "path/to/my/template.html"

My template is:

<header class="page-header">
  <h1 class="page-title heading">{{ pageTitle }}</h1>
  <div class="page-header-toolbar toolbar" ng-transclude="toolbar">
    <!-- "toolbar" transcluded content should go here -->
  </div>
</header>

And finally, when I use the directive, I'm using it this way:

<my-custom-page-header-directive page-title="Title">
  <toolbar-slot>
    <button>Button</button>
    <button>Another button</button>
  </toolbar-slot>
</my-custom-page-header-directive>

The problem is, in the DOM it ends up as something like this, with an extraneous toolbar-slot element mixed into the transcluded content:

<header class="page-header">
  <h1 class="page-title heading">Title</h1>
  <div class="page-header-toolbar toolbar">
    <toolbar-slot>
      <button>Button</button>
      <button>Another button</button>
    </toolbar-slot>
  </div>
</header>

Is there a way (using ngTransclude) to only transclude the contents of the slot element?


Solution

  • Looks like the answer is no, there isn't a way to do that as of right now.

    An open issue on the Angular.js repository shows that there are misgivings about implementing the ability to use ngTransclude that way:

    I'm not a fan of adding a replace functionality to the slot transclusion. It would introduced the same problems we have with normal "replace" and transclude: element.

    But, apparently, you "can actually do this manually if your really need it".