Search code examples
javascriptangularjsangularjs-directiveangularjs-components

How to not render transclusion slot when it's not provided in AngularJS?


I have an AngularJS component which uses transclusion with 2 transclusion slots. One of them (messageHeading) is optional and sometimes will not be provided at all. Code below:

message.js

import template from "./messsage.html";

angular.component('message', {
    transclude: {
        heading: '?messageHeading',
        content: 'messageContent'
    },
    template
});

message.html

<aside class="message">
    <h2 class="message__heading"
        ng-transclude="heading"></h2>
    <p class="message__paragraph"
       ng-transclude="content"></p>
</aside>

Question

How can I not render <h2> element at all, when messageHeading is not provided? In the current default behaviour it's rendered, only with empty contents, but I want it to never appear in the DOM.

Using ngIf on <h2> seems like a natural way to do it, but I don't know how to write a condition which would be true only when the transclusion argument was provided.


Solution

  • I worked it out myself. There is $transclude service, which provides method isSlotFilled(nameOfTheSlot) to check if the slot has been filled. You can use that as a value of the ngIf condition and so render <h2> only when the slot has been filled.

    message.js

    import template from "./messsage.html";
    
    
    class MessageController {
        constructor($transclude) {
            this.hasHeading = $transclude.isSlotFilled('heading');
        }
    }
    
    
    angular.component('message', {
        transclude: {
            heading: '?messageHeading',
            content: 'messageContent'
        },
        controller: MessageController,
        template
    });
    

    message.html

    <aside class="message">
        <h2 class="message__heading"
            ng-if="$ctrl.hasHeading"
            ng-transclude="heading"></h2>
        <p class="message__paragraph"
           ng-transclude="content"></p>
    </aside>