Keep CSS classes out of your Angular controllers
In Angular (and in general) I'm a big fan of keeping view logic out of my controllers, and one place where I see this not happening is CSS classes and the use of ng-class.
If you're not familiar with ng-class, it's a special directive to allow binding of expressions and have them put as, yes, the class of an element. A very common use of ng-class goes something like this:
<p ng-class="{{active}}">Class applied!</p>
<script>
function MySimpleCtrl() {
$scope.active = 'active';
...
So in the controller we're setting the particular class that should be displayed; so say we have a class 'inactive' - we simply set the $scope.active variable to 'inactive' and voila, we the class is set in the view.
But ng-class is even cleverer than that:
ng-class accepts three different types of value:
- A string value (name of class)
- An array of strings (classes to be applied)
- An object + expression to evaluate against
And it's option 3 that's of interest; the syntax looks something like this:
ng-class="{object of key/value pairs}[expression to evaluate]"
Basically ng-class evaluates the expression (in the square brackets) and then uses that as the key for the object; the value that the key relates to is the class that applies.
This allows us to turn the $scope.active
value into a real boolean (which is really how we're using it) - no view logic in controllers, controllers are easier to test and can be re-used.
Here's the simple example:
<p ng-class="{true: 'active', false: 'inactive'}[isActive]">
Class applied
!</p>
<script>
function MySimpleCtrl() {
$scope.isActive = true;
And you can can see it working in this JSFiddle
If you're using some sort of set of conditional expressions (i.e. toggles) then you can use another, very similar syntax like this:
ng-class="{'selected': isSelected, 'blue': isBlue}"
Here the selected
class will be applied if isSelected
is true. The same with the blue
class. Angular will apply as many of those that are true, so you could set the class to selected and blue.
Written by Oliver Tupman
Related protips
7 Responses
BEAUTIFUL!! This explanation should be in the Angular docs... The example they give there is terrible, and I knew there must be a better way than having to use class names in the controller. Thank you.
Thank you! Nicely explained and ditto, this should be in the examples
Your example solved my problem. Thank you.
Thank you so much for this article. I had no idea something like
ng-class="{true: 'active', false: 'inactive'}[isActive]"
was valid. And it was just the thing I was looking for! Curious how you figured that one out :)
1000x thanks Oliver for the simple explaination, and the great simple example
Oliver, thanks for the explanation and the simple demo.
Thanks, this was clear and helped.