How do I apply an AngularJS directive based on a class set by ng-class?

angularjs, angularjs-directive

Solution

`ng-class` just sets classes on the DOM, after the compilation process.

Perhaps a better way to apply the directive would be through an HTML attribute:

<div test-case>

Of course, this is not conditional, but I would leave the conditioning to the directive:

<div ng-app="example" ng-controller="exampleCtrl">
    <div test-case condition="dynamicCondition">Hello</div>
    <input type="checkbox" ng-model="dynamicCondition"/> Condition 
</div>

and

angular.module('example', [])
    .controller('exampleCtrl', function ($scope) {
        $scope.dynamicCondition = false;
    })
    .directive('testCase', function () {
    return {
        restrict: 'A',
        scope: {
            'condition': '='
        },
        link: function (scope, element, attrs) {
            scope.$watch('condition', function(condition){
                if(condition){
                    element.css('color', 'red');
                }
                else{
                    element.css('color', 'black');
                };
            });
        }
    }
});

Notice the directive name is `testCase`rather than `testcase`, the `scope: {'condition': '='},` bit ensures that the condition attribute is synchronized and available as `scope.condition` and the `watch` evaluates the second argument every time the expression on the first changes value. JsFiddle over here.

Perhaps you should also look into `ng-switch`:

<div ng-switch="conditionFunction()">
  <div ng-when="true" test-case>Contents when conditionFunction() returns true</div>
  <div ng-when="false">Contents when conditionFunction() returns false</div>
</div>

Problem

I'm trying to conditionally apply a directive to an element based on its class. Here's a simple case of my issue, see the results in this fiddle. For this example, I'm using the map of class names to booleans form of `ng-class` with `true`; in my actual case I'd like to use the boolean result of a function. Markup: ``` <div ng-app="example"> <div class="testcase"> This will have the directive applied as I expect </div> <div ng-class="{'testcase':true}"> This will not have the directive applied but I expect it to </div> </div> ``` JS: ``` angular.module('example', []) .directive('testcase', function() { return { restrict: 'C', link: function(scope, element, attrs) { element.css('color', 'red'); } } } ); ``` Why isn't the directive being applied to the `div` that's getting its class through `ng-class`? Am I misunderstanding something about the order in which AngularJS is processing directives? How should I be conditionally applying a directive to an element based on the evaluation of an expression?

Original source