1

I hav a directive that looks roughly like this, with an ng-class in the template:

module.directive('myDirective', [function() {
    return {
        restrict: 'E',
        template: `<div ng-class="{'foo-expanded': expanded, 'foo': !expanded}"><div>`
        //...
    }
}]);

My problem is, my classes from the ng-class are applied to the div, which ends up being nested inside of the directive element after the directive is compiled: <my-directive><div>...</div></my-directive>.

Is there any way to apply the classes to the root <my-directive> element instead? I know I can dynamically add the class using javascript in the link function or controller instead of the ng-class, but I am looking for a way to avoid this.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
elethan
  • 16,408
  • 8
  • 64
  • 87

2 Answers2

2

You can do that using the link function which gives you access to the created element ( directive )

module.directive('myDirective', [function() {
    return {
        restrict: 'E',
        template: `<div ng-class="{'foo-expanded': expanded, 'foo': !expanded}"><div>`
        link: function(scope, element, attrs) {        
           element[0].classList.add('test')
        }
    }
}]);
Taki
  • 17,320
  • 4
  • 26
  • 47
  • 1
    Thanks for your suggestion. However, I would like to avoid adding the classes with javascript from the link function or controller. The problem is, that I would have to introduce a lot more complexity to get the same functionality as the `ng-class`. For example, I would need the method that toggles the `expanded` flag to to add and remove classes each time the flag changes (or something similar to that). However, your solution is likely to be the path I take if I can't figure out anything else, in which case I will select your answer. – elethan Feb 24 '20 at 20:10
1

This answer shows two different ways

  • Manipulate the classes from the controller
  • Use replace: true (deprecated)

Manipulate the classes from the controller

If you don't want to use replace: true, you can manipulate the directive's root classes from the controller by injecting $element.

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        template: `
          <div ng-class="{'foo-expanded': expanded, 'foo': !expanded}">
             MY DIRECTIVE
          <div>
        `,
        controller: function($element) {
            $element.addClass("foo test test2");
            $element.toggleClass("foo-expanded");
            $element.removeClass("test2");
        }
    }
});

The DEMO on PLNKR

For more information, see


Use replace: true (deprecated)

Another approach is to use replace: true:

module.directive('myDirective', [function() {
    return {
        restrict: 'E',
        replace: true,
        template: `<div ng-class="{'foo-expanded': expanded, 'foo': !expanded}"><div>`
        //...
    }
}]);

Keep in mind that the replace property is deprecated in AngularJS and has been removed in the new Angular (v2+).

For more information, see

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95