I have written a custom directive called 'news' in AngularJS 1.5.
It's layout is as follows:
<div class="row">
    <div class="largeText shadow1" ng-transclude="heading"></div>
    <div class="mediumText shadow2" ng-transclude="content"></div>
</div>
The JavaScript file of this directive is as follows:
return {           
    restrict: 'E',
    transclude: {
      'heading': 'heading',
      'content': 'content'
    },
    scope: {
        //Some parameters here
    },
    templateUrl: '/directives/news.html'
};
As you see, my news directive has two children, called heading and content fields. It can be used as follows:
<news>
    <heading>
        //Any content goes here
    </heading>
    <content>
        //Any content goes here
    </content>
</news>
So far, the directive works fine. I mean, as long as heading and content sections are filled with some content, the directive shows them as expected. However, I am trying to make these transclusion slots not mandatory. Whenever I use the directive as:
<news>
    <heading></heading>
</news>
AngularJS throws an error saying that I have not filled the content slot. Is it ever possible to make these slots optional?
The ng-transclude directive facilitates AngularJS to capture everything that is put inside the directive in the markup and use it somewhere in the directive's template.
Essentially, transclusion in AngularJS is/was taking content such as a text node or HTML, and injecting it into a template at a specific entry point. This is now done in Angular through modern web APIs such as Shadow DOM and known as “Content Projection”.
I can't really find where it is in the actual documentation, but based on an example I saw, I believe that you can use a ? before the value to make the slot optional.
Example:
transclude: {
  'heading': 'heading',
  'content': '?content'
}
This comes from the example in angular docs at https://docs.angularjs.org/api/ng/directive/ngTransclude#multi-slot-transclusion. It is in the app.js.
You can also add a default for the cases where the slot is optional, by doing something like this:
<div class="largeText shadow1" ng-transclude="heading">Default stuff for the slot goes here</div>
Edit: actually I found it in the documentation. It says in this section https://docs.angularjs.org/api/ng/service/$compile#transclusion:
If the element selector is prefixed with a
?then that slot is optional. For example, the transclude object{ slotA: '?myCustomElement' }maps<my-custom-element>elements to theslotAslot, which can be accessed via the$transcludefunction or via thengTranscludedirective.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With