1

Using AngularJS, I want the background color of a table cell to depend on the value. This works, is it the most efficient way? I have several tables and my example only shows three score types, but I actually need to base the formatting on 15 types.

<td data-ng-repeat="score in scoreTypes"
    ng-class="{vGood: score.score_type == '3',
               good:  score.score_type == '10',
               avg:   score.score_type == '12'}">{{score.score_type}}</td>
Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
tcrafton
  • 97
  • 2
  • 10
  • possible duplicate of [What is the best way to conditionally apply a class with angularjs?](http://stackoverflow.com/questions/7792652/what-is-the-best-way-to-conditionally-apply-a-class-with-angularjs) – James Aug 20 '14 at 17:22

3 Answers3

2

One way is to push your data into scope in controller:

$scope.scoreCSSClass = {
  '3': 'vGood',
  ...
};

and

<td data-ng-repeat="score in scoreTypes" ng-class="scoreCSSClasses[score.score_type]">{{score.score_type}}</td>

And other solution, if you need more control:

Create and bind to the scope some function in your controller.

$scope.scoreCSSClass = function (score_type) {
  if (score_type == '3') {
    return 'vGood';
  } else if (score_type == '10') {
    return 'good';
  } else if (score_type == '12') {
    return 'avg';
  } else {
    return 'default';
  }
};

And use it like

<td data-ng-repeat="score in scoreTypes" ng-class="scoreCSSClass(score.score_type)">{{score.score_type}}</td>
Nikolay Baluk
  • 2,245
  • 1
  • 19
  • 22
  • I thought all of these answers were pretty slick, went with the first suggestion in this answer but will try the others out when I have more time. Thanks! – tcrafton Aug 20 '14 at 18:11
1

If you have several tables with the same login for classes then you could move it into a function on your controller. e.g.

JS

var MyCtrl = function($scope) {
    $scope.getScoreClass = function(score) {
        switch (score) {
            case '3':
                return 'vGood';
            case '10':
                return 'good';
            case '12':
                return 'avg';
        }
    }
}

HTML

<td data-ng-repeat="score in scoreTypes"
    ng-class="{{getScoreClass(score)}}">{{score.score_type}}</td>
rob
  • 17,995
  • 12
  • 69
  • 94
1

Try to avoid bloating your $scopes/Controllers. Make your application code extensible and reusable.

You can host your hash of scores to class names in a constant (to make them constant and easier to manage):

angular
    .module("yourModule")
    .constant("SCORE_TYPES", {
        "3" : "vGood",
        "10" : "good",
        "12" : "avg"    
    });

And create a filter to return a class name from a score using the map. The filter injects the constant:

angular
    .module("yourModule")
    .filter("getClassByScoreType", ["SCORE_TYPES", function(TYPES) {
        return function(scoreType) {
            return TYPES[scoreType] || ""; // default class name
        };    
    }]);

In your HTML, you don't need the additional directive, ng-class, as you're evaluating the class name directly into the attribute:

<td data-ng-repeat="score in scoreTypes"
    class="{{ score.score_type | getClassByScoreType }}">{{score.score_type}}</td>
SirTophamHatt
  • 1,581
  • 17
  • 23