2

I am trying to apply multiple css classes using ng-class. I am doing the following.

  <span ng-class="{'label':true, 'label-success':status=='Ok', 'label-warning':status=='Warnings', 'label-important':status=='Critical'}">{{status}}</span>

See the working plunker here. Is there a shorter way? Another way which I tried is calling controller function which return a list of CSS classes but I'd prefer not to pollute my controller with CSS class names.

3
  • 2
    Just curious, how might you imagine you could make it any shorter than it already is, since each class needs to be applied conditionally? Commented Mar 9, 2013 at 3:50
  • Well better if not shorter. Commented Mar 10, 2013 at 5:45
  • I have put all 3 options (using ng-class, using directive and using controller) in here Commented Mar 10, 2013 at 7:31

2 Answers 2

6

A good method for refactoring DOM functionality you deem to be too complex is to create a directive; for example, you could create a directive that simply applies a class conditionally based on the string:

<span status-class='status'>{{status}}</span>
app.directive('statusClass', function() {
  return function(scope, elem, attrs) {
    scope.watch(attrs.statusClass, function(value) {
      if(value == 'Ok')
        elem.addClass('label-success');
      else
        elem.removeClass('label-success');
      // ... etc ...
    });
  };
});

There's more code behind the scenes but your view is simplified

If your class names vary and you can't use a single directive like this, you'll probably find using ng-class as in your question is the quickest way to get the desired effect.

Sign up to request clarification or add additional context in comments.

1 Comment

I really like this approach. Awesome job.
2

To make it in shorter way you may try to make status names and class names match and then something like this:

<span class="label" ng-class="'label-'+status">{{status}}</span>

BUT...

In real life thing may be more complicated. Since you may have more statuses than bootstrap alerts and since status labels in your application not exactly the same as bootstrap class names, this may be optimal:

<span class="label" ng-class="alert_class(status)">{{status}}</span>

and in your controller:

  $scope.alerts = {
    'Warnings': 'label-warning',
    'Ok': 'label-success',
    'Critical': 'lablel-important'
  };

Finally, if statuses in your code, status labels and bootstrap classes are all different, you will need more complex struture, like this:

$scope.statuses =
  warning:
    label: 'Warnings'
    class: 'label-warning'
  ok:
    label: 'It`s OK'
    class: 'label-success'
  critical:
    label: 'Something is going wrong...'
    class: 'label-important'

and use it this way:

<span class="label" ng-class="statuses[status].class">{{statuses[status].label}}</span>

2 Comments

Thanks. This is what I was doing but am trying to avoid putting template logic in controllers if possible.
@Kamlesh, then you should use directive and put this in it

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.