2

I have written a custom directive in AngularJS. And I have to use isSlotFilled method of $transclude. The JavaScript of the directive:

define(['../directives-module'], function (directivesModule, $scope, $transclude) {    
    directivesModule.directive('news', function() {
        return {           
            restrict: 'E',
            replace: true,
            transclude: {
              'heading': 'heading',
              'content': '?content'
            },
            scope: {
                'cmsContent': '@'
            },
            templateUrl: 'directives/news.html',
            link: function(scope, element, attrs, ctrl, transclude){
                console.log($transclude.isSlotFilled(content));
            },
        };
      });    
});

I have tried to output a console.log() to check the method works. The console.log() above does not work, saying:

TypeError: Cannot read property 'isSlotFilled' of undefined

Actually, I have to use this method on the HTML file of the directive. The file news.html contains:

<div class="row">
    <div class="largeText shadow1" ng-transclude="heading"></div>
    <div class="mediumText shadow2" ng-transclude="content"
         ng-class="{'hide' : $transclude.isSlotFilled(content)}">
    </div>
</div>

As you see in the ng-class, it will hide the div if the content slot is not filled. However the condition here inside ng-class always returns false. I'm sure I am missing something at injecting $transclude. What should I do to properly use this method from the news.html?

3
  • which version of angular you are using? Commented Mar 29, 2016 at 9:10
  • @VishalRajole It's 1.5.0 Commented Mar 29, 2016 at 10:12
  • You're not injecting $transclude to directive, whatever it is. Is it a module? Service? The question says nothing on this. Commented Mar 29, 2016 at 10:38

1 Answer 1

2

I'm not sure what you're attempting to do using your module system but in any case: $transclude is not a service but a function that's injectable to directive and component controllers. The same goes for $scope.

The link function gets called with the transclude function so you may use it directly. Also remember to put quotes around content.

define(['../directives-module'], function (directivesModule) {    
    directivesModule.directive('news', function() {
        return {           
            restrict: 'E',
            replace: true,
            transclude: {
              'heading': 'heading',
              'content': '?content'
            },
            scope: {
                'cmsContent': '@'
            },
            templateUrl: 'directives/news.html',
            link: function(scope, element, attrs, ctrl, transclude){
                console.log(transclude.isSlotFilled('content'));
            },
        };
      });    
});

To access it in a template you can add it as a property to the scope. You can do that in the link function if you want:

function(scope, element, attrs, ctrl, transclude){
    console.log(transclude.isSlotFilled('content'));
    scope.transclude = transclude;
}

// Or maybe
function(scope, element, attrs, ctrl, transclude){
    console.log(transclude.isSlotFilled('content'));
    scope.hasContent = transclude.isSlotFilled('content');
}
Sign up to request clarification or add additional context in comments.

2 Comments

THANK YOU. I could not for the life of my figure out how to get hold of that transclude function
it's not my question but I'm sure @Faruk Yazıcı can help you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.