invmatt
invmatt

Reputation: 123

Angular directive class not being applied

Using element.addClass doesn't add the class onto the element. If I remove class="progress-radial progress-{{percentage}}" from the template it does however work.

Not sure what exactly is going wrong as the code fires correctly, just doesn't seem to want to add a new class if the attribute already exists.

angular.module(moduleName, [])
.directive('npProgress', function() {
  return {
    restrict: 'AE',
    replace: true,
    scope: {
      percentage: '@'
    },
    template: '<div class="progress-radial progress-{{percentage}}">' +
    '<div class="overlay">{{percentage}}</div>' +
    '</div>',
    link: function(scope, element, attrs) {
      if ( scope.percentage > 50 ) {
        element.addClass('progress-radial--positive');
      }
    }
  }
});

Upvotes: 0

Views: 422

Answers (2)

georgeawg
georgeawg

Reputation: 48948

Replace the interpolated class with the ng-class directive.

ERRONEOUS

//AVOID interpolated class
template: '<div class="progress-radial progress-{{percentage}}">' +
               '<div class="overlay">{{percentage}}</div>' +
          '</div>',

USE ng-class="'progress-'+percentage":

template: '<div class="progress-radial" ' +
                'ng-class="' +"'progress-'" + '+percentage">' +
              '<div class="overlay">{{percentage}}</div>' +
          '</div>',

The binding of the interpolated string was fighting the changes by the custom directive.

This is a Known Issue

Known Issues

Dynamically changing an interpolated value

You should avoid dynamically changing the content of an interpolated string (e.g. attribute value or text node). Your changes are likely to be overwriten, when the original string gets evaluated.

--AngularJS Developer Guide -- Interpolation -- Known Issues

Upvotes: 1

Sravan
Sravan

Reputation: 18647

Try adding the class using angular.element

Here is the Documentation.

Also use parseInt on scope.percentage since you are sending string percentage using @ binding.

parseInt converts the string to integer and then compares.

angular.module(moduleName, [])
.directive('npProgress', function() {
  return {
    restrict: 'AE',
    replace: true,
    scope: {
      percentage: '@'
    },
    template: '<div class="progress-radial progress-{{percentage}}">' +
    '<div class="overlay">{{percentage}}</div>' +
    '</div>',
    link: function(scope, element, attrs) {
      if ( parseInt(scope.percentage) > 50 ) {
        angular.element(element).addClass('progress-radial--positive‌​');

      }
    }
  }
});

Upvotes: 0

Related Questions