0

I am working on an Angular 1 app and I need to call different directives based on a value in a ng-repeat loop. I am using ng-if so far which renders that directive if it matches the condition but what I am thinking is that if I got 100 directives after some time, then I will be using 100 ng-ifs and I am thinking there must be some better solution for this.

Here's some of my code

Template which calls the directive

<render-directive ng-if="data.length !== 0" data="data"></render-directive>

Template of renderDirective

<div ng-repeat="element in data">
  <div ng-if="element.item === 'motor'">
    <render-motor motor-id="element.id" name="element.item"
              checked="element.params.switch"></render-motor>
  </div>

  <div ng-if="element.item === 'adc'">
    <render-adc adc-id="element.id" name="element.item"></render-adc>
  </div>
</div>

For sake of simplicity, I've only shown two directives but in real I am already calling more than 10 directives and it can go upto 100 in future.

So does anyone can tell me a better way to do this, where I won't have to use ng-if for every directive?

Please do let me know if I haven't cleared something in question.

UPDTAE

For clearing what I am exactly looking for, I have an array which has 'item' propery and according to that property I want to call a directive. So for eg,

  • for item = "motor", I want to call motorDirective
  • for item = "switch", I want to call switchDirective
  • for item = "led", I want to call ledDirective

and so on.

4
  • What you exactly need? do loop different data with different structure or data with different template ? Commented Jan 2, 2017 at 13:02
  • Please see the update Commented Jan 2, 2017 at 13:18
  • Look into using the ng-switch directive. It has less overhead than using several ng-if directives. Commented Jan 2, 2017 at 21:13
  • @myke_11j please check my updated answer, it should be better now. Commented Jan 3, 2017 at 17:22

2 Answers 2

1

I had to update my answer as it was tricky to pass a scope to ng-bind-html.

Moreover a solution with a polymorphic directive is way nicer as it also save the declarative part of a table driven solution.

The final solution where the interesting part is the polymorph directive:

var app = angular.module('app',[]);

app.controller('elementsCtrl',['$scope', function($scope){
  
  $scope.elements = [
    {type: 'motor'},
    {type: 'adb'},
    {type: 'led'},
    {type: 'motor'}
  ];
}]);

app.directive('polymorph', ['$compile', function($compile){
  return{
    restrict: 'E',
    scope: {
      type: '@',
      item: '='
    },
    link: function(scope, element, attr){
      var result = $compile('<div '+ scope.item.type +'></div>')(scope);
      element.append(result);
    }
  }
}]);

app.directive('motor', function(){
  return{
    restrict: 'A',
    replace: true,
    template: '<div style="color:blue;">{{item.type}}</div>'
  }
});


app.directive('led', function(){
  return{
    restrict: 'A',
    replace: true,
    template: '<span style="color:green;">{{item.type}}</span>'
  }
});

app.directive('adb', function(){
  return{
    restrict: 'A',
    replace: true,
    template: '<p style="color:red;">{{item.type}}</p>'
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<div ng-app="app" ng-controller="elementsCtrl">
  <div ng-repeat="element in elements">
    <polymorph type="{{element.type}}" item="element"></polymorph>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

this might do it for me...I will try this. Thanks
Yes I needed something like this. $compile was the solution for me. Thanks Piou
1

You need to use $compile in the renderDirective .

In the compile step , we need to compile the dynamically required directive .

1 Comment

Can you post a snippet of how I can use compile block in a directive to call different directives? Thanks

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.