0

I am trying to create a directive that adds some html code but also adds additional attributes/directives.

Using the code below, an ng-class attribute is indeed added, but it seems angular does not recognize it as a directive anymore. It is there, but it has no effect.

How can I get it to work? Thanks.


The Angular code:

angular.module('myModule', [])
    .directive('menuItem', function () {
        return {
            restrict: 'A',
            template: '<div ng-if="!menuItem.isSimple" some-other-stuff>{{menuItem.name}}</div>'
                     +'<a ng-if="menuItem.isSimple" ng-href="{{menuItem.link}}">{{menuItem.name}}</a>',
            scope: {
                menuItem: '='
            },
            compile: function (element, attrs) {
                element.attr('ng-class', '{active : menuItem.isActivated()}');
            }
        }
    });

And the html:

<li menu-item="menuItem" ng-repeat="menuItem in getMenuItems()" />

EDIT: The solution by @Abdul23 solves the problem, but another problem arises: when the template contains other directives (like ng-if) these are not executed. It seems the problem just moved.

Is it possible to also make the directives inside the template work?
Or perhaps insert the html using the compile function instead of the template parameter. Since I want a simple distinction based on some value menuItem.isSimple (and this value will not change), perhaps I can insert only the html specific to that case without using ng-if, but how?

neXus
  • 2,005
  • 3
  • 29
  • 53

1 Answers1

2

You need to use $compile service to achieve this. See this answer.

For your case it should go like this.

angular.module('myModule', [])
.directive('menuItem', function ($compile) {
    return {
        restrict: 'A',
        template: '<a ng-href="{{menuItem.link}}">{{menuItem.name}}</a>',
        scope: {
            menuItem: '='
        },
        compile: function (element, attrs) {
              element.removeAttr('menu-item');
              element.attr('ng-class', '{active : menuItem.isActivated()}');
             var fn = $compile(element);
             return function(scope){
                        fn(scope);
                     };
        }
    }
});
Community
  • 1
  • 1
Abdul23
  • 5,265
  • 2
  • 16
  • 23
  • This works, and this answered the question as it was, but now directives inside the template are not executed. Do you have an idea on how to solve that? I updated the question with more info. – neXus Jun 17 '15 at 15:11
  • @neXus As a quick fix solution you can try appending your template inside compile function as `element.append(your template string)` before calling $compile() and remove `template:your template string` from directive;Let me know if this works for you. – Abdul23 Jun 18 '15 at 07:10
  • ugh, my simplified case works, but as soon as I add the `ng-repeat` it no longer does :( – neXus Jun 18 '15 at 12:07
  • I dont think you need to use a directive for your case.Here's a simple [plunk](http://plnkr.co/edit/7i1jF4IYmhNFhH8tz7tR?p=preview) that can solve your problem. – Abdul23 Jun 19 '15 at 08:48