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?
To add a conditional class in Angular we can pass an object to ngClass where key is the class name and value is condition i.e., true or false as shown below. And in the above code, class name will be added only when the condition is true.
yes , you can do it. Did you try it? What happened? You can use both class and ngClass as the first one gives you the opportunity to apply a class that you want to implement in all cases under any circumstances and the later to apply classes conditionally.
Definition and Usage The ng-class directive dynamically binds one or more CSS classes to an HTML element. The value of the ng-class directive can be a string, an object, or an array. If it is a string, it should contain one or more, space-separated class names.
Directives are markers on a DOM element that tell AngularJS to attach a specified behavior to that DOM element or even transform the DOM element and its children. In short, it extends the HTML. Most of the directives in AngularJS are starting with ng- where ng stands for Angular.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With