Abhirath Mahipal Abhirath Mahipal - 2 months ago 9
AngularJS Question

How to conditionally hide elements of an Angular Directive

I have an Angular Directive.

Here is the replica of it's template

<div>
<div>
<div></div>
<div></div> <!-- to be hidden in some places -->
<div></div>
</div>
</div>


This directive isn't dynamic. It just renders once when the page is loaded. I want to use the same directive in some places but without a particular div. What's the best way to go about it?

I've thought about and researched the following



I am relatively new and I might be wrong with my approach. Please point the mistakes that I may have made.

<div ng-show="somemodel"></div>



  • Use some model to show or hide it. But the problem is that I will have to create a model/variable in every respective controller.

  • Change the link function depending on the value passed to the directive and hide the div

  • I don't see the use of a watch as nothing's going to change once the user loads a page.



Is there any way to pass in a value/config while using the directive? This way everything related to that directive can be clubbed together.

<div directive-name showParticularDiv = "true" />
<div directive-name showParticularDiv = "false" />


Edit after implementation of some ways.

View

<div date-picker-directive></div>


Template

<div class="timebuttons">
<div class="ui button" ng-click="vm.getPredefinedDataButtons(365)">LAST YEAR</div>
<div class="ui button" ng-click="vm.getPredefinedDataButtons(90)">LAST QUARTER</div>
<div class="ui button" ng-click="vm.getPredefinedDataButtons(31)">LAST MONTH</div>
<div class="ui button" ng-click="vm.getPredefinedDataButtons(7)">LAST WEEK</div>
<div class="ui button" ng-click="vm.getPredefinedDataButtons(0)" ng-show="vm.showToday">TODAY</div>
<div class="ui button blackbody" id="givedate" ng-click="showRange = !showRange">CUSTOM RANGE</div>
</div>


This works. If I use a variable from the controller to hide/show the div, it works fine.

If I use the directive's scope instead of a model from the controller, ng-click stops working.

<div date-picker-directive show-today="false" />


ng-click in the template stops working.

Answer

The best way is to pass through attributes(as in your last code block) and bind in scope directive's property. More about scope binding you can read here. Also, important to remember that directive name and it's attributes will be converted to kebab-case, so if you have attribute or directive with name myItem it should be written as my-item in HTML.

angular
.module('app', [])
.controller('mainCtrl', function($scope) {
  $scope.show = false;
}).directive('dynamicDirective', function() {
  return {
    restrict: 'A',
    scope: {
      showHidden: '=?'
    },
    template: '<div ng-show="showHidden">hidden</div>'
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="mainCtrl">
  <input type="checkbox" ng-model="show">Show hidden
  <div dynamic-directive show-hidden="show"></div>
</div>

In your case directive cannot call controller's function until you pass it through attributes or share scope with directive(example based on the first option):

angular
.module('app', [])
.controller('mainCtrl', function($scope) {
  $scope.show = false;
  $scope.getPredefinedDataButtons = function(amount) {
    console.log('Called with amount', amount);
  };
}).directive('dynamicDirective', function() {
  return {
    restrict: 'A',
    scope: {
      showHidden: '=?',
      callback: '&?'
    },
    templateUrl: '/templates/dynamic-dir.html',
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="mainCtrl">
  <input type="checkbox" ng-model="show">Show hidden
  <div dynamic-directive show-hidden="show" callback="getPredefinedDataButtons(amount)"></div>
  <script type="text/ng-template" id="/templates/dynamic-dir.html">
    <div class="timebuttons">
    <div class="ui button" ng-click="callback({amount: 365})">LAST YEAR</div> 
    <div class="ui button" ng-click="callback({amount: 90})">LAST QUARTER</div>
    <div class="ui button" ng-click="callback({amount: 31})">LAST MONTH</div> 
    <div class="ui button" ng-click="callback({amount: 7})">LAST WEEK</div>
    <div class="ui button" ng-click="callback({amount: 0})" ng-show="showHidden">TODAY</div>
    <div class="ui button blackbody" id="givedate" ng-click="showRange = !showRange">CUSTOM RANGE</div>
</div>
  </script>
</div>

Please pay attention to how I pass arguments to callback from directive it's very important to know that Angular using named arguments in this case.