5

I want to apply a simple directive conditionally using ngAttr. I don't understand why my directive is always displayed. So if I have an undefined / false variable I want to apply my directive: dirr.

When using ngAttr, the allOrNothing flag of $interpolate is used, so if any expression in the interpolated string results in undefined, the attribute is removed and not added to the element.

My code pen

<div ng-app="myApp" ng-controller="MainController" class="container-fluid">
    <h2 ng-bind="currentVersion"></h2>
    <hr>
    <div ng-attr-dirr="hidden || undefined">Default div</div>
</div>

angular.module('myApp',[])
 .directive('dirr', function(){
   return {
     restrict:'AE',
     template:'<div>Div from directive</div>'
   }
 })
 .controller('MainController',['$scope', function($scope){
   $scope.currentVersion = 'Angular 1.3.6';
   $scope.hidden = undefined;
 }])
; 
4
  • 2
    FYI you should avoid naming your own variables, directives etc under the ng namespace ($scope.ngVar). Thats for core angular components and could cause confusion for future developers. Commented Feb 25, 2016 at 9:12
  • @ste2425 it's a fast example, please be on topic !! Commented Feb 25, 2016 at 9:14
  • 2
    He says "FYI" as side note, not "I am on the topic"! Commented Feb 25, 2016 at 9:16
  • @asdf_enel_hak, ste2425 ok, I changed the variable name. Commented Feb 25, 2016 at 9:21

3 Answers 3

4

You can make use of AngularJS's inbuilt directive ng-if to check for the condition and execute it conditionally.

Example:

<div ng-if="{some_condition}">
    <dirr></dirr> <!--Execute the directive on the basis of outcome of the if condition-->
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

I can't use ng-if in my context
why, wat's the issue? or go with ng-switch.
1

Form documentation

All of the Angular-provided directives match attribute name, tag name, comments, or class name

so whenever angular matches a diretive with attribute name,it compiles the template and renders the html irrespective of attribute value.

anyway you can use scope in directive template.so use ng-hide with scope's hidden property

angular.module('myApp',[])

 .directive('dirr',function(){
     return{
        restrict:'AE',
        template:'<div ng-hide="hidden">Div from directive</div>',
     }
 })
 .controller('MainController',['$scope', function($scope){
     $scope.hidden=false;
 }]);

Comments

0

The answers are true and the sample code you provided works for small issues, but when it comes resolving this problem on large applications you may want to take this approach:

Updated Pen

<div ng-app="myApp" ng-controller="MainController" class="container-fluid">
    <h2 ng-bind="currentVersion"></h2>
    <hr>
    <div dirr value="{{hidden}}">Default div</div>
  </div>

.directive('dirr', function($log){
  var directiveInstance =  {
    restrict:'AE',
    scope:{
      value:'@'
    },
    link: function (scope, element, attrs, ctrl) {
      if(attrs.value === 'true'){
        console.log('directive on !!');
        $log.debug('element',element);
        element[0].innerHTML = '<div>hello ' + attrs.value + '</div>';
      }
      else {
        console.log('directive off !!');
      }
    }
  }
  return directiveInstance;
})

This is more tidy and you may not want to duplicate your code using ngIf or ngSwitch directives in seperate divs when you have something like:

<table>
  <thead dirr value="{{statement}}">
    <tr>
     <th>
        CrazyStuffHere...
     </th>
     <th>
        CrazyStuffHere...
     </th>
     ....
    </tr>
  </thead>
</table>

4 Comments

Except any angular bindings in your added HTML won't be bound. You would need to use the $compile service, not jquery/jqlite.
@ste2425 provide example, I'm not sure what you meant.
Hope this will help. jsfiddle.net/q9cqquLe It may be better to have this logic not in every directive, but have a single utility one that does this logic for you being passed the directive name to conditionally apply.
Oohh, I see now, yes, that makes sense. Provide a thread answer so I can accept 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.