Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS optional ng-transclude

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?

like image 954
Faruk Yazici Avatar asked Mar 28 '16 14:03

Faruk Yazici


People also ask

What is Ng transclude in AngularJS?

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.

What is angular Transclusion?

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”.


1 Answers

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 the slotA slot, which can be accessed via the $transclude function or via the ngTransclude directive.

like image 190
CShark Avatar answered Sep 20 '22 07:09

CShark