Ricardo Mota
Ricardo Mota

Reputation: 89

Dynamically select directive based on data

I am trying to populate a table based on an array of objects. This array doesn't contain objects of the same type and for each row I'd like a completely different style and, onclick function, basically a completely different behaviour.

For instance:

var data=[
  {
    type:'dir-b',
    data: { ... }
  },
  {
    type:'dir-b',
    data: { ... }
  },
  {
    type:'dir-c',
    data: { ... }
  }
]

For object type dirB I want a template and controller and for dirC a completely different function and template.

The solution I found was to create 3 directives. One of which will run to determine one of the other two directives to add based on data.

.directive("dirA", function($compile){
  return{
    restrict:'A',
    priority:1000,
    terminal:true,
    link: function(scope, element, attribute){
      element.removeAttr("dir-a");//prevent endless loop
      element.attr(attribute.type,"");
      $compile(element)(scope);
    }
  }
})
.directive("dirB", function($compile){
  return{
    restrict:'A',
    replace:true,
    link: function(scope, element, attribute){
        console.log("dirA");
    }
  }
})
.directive("dirC", function($compile){
  return{
    restrict:'A',
    replace:true,
    link: function(scope, element, attribute){
        console.log("dirC");
    }
  }
});

Using <tr dir-a type='{{d.type}}' ng-repeat='d in data'/> is not having the desired effect. Either I give dirA a priority of 0 and it can parse the attribute but it's repeated more times than the array size, or I give it a priority of 1000 and it can't parse the b.type and use it as a literal.

Does anyone have a solution for this?

Upvotes: 4

Views: 80

Answers (2)

Ricardo Mota
Ricardo Mota

Reputation: 89

Not sure this was the best solution but it was the solution I found.

<table>
  <tbody ng-repeat='d in data'>
    <tr ng-if='d.type=="dir-b"' dir-b></tr>
    <tr ng-if='d.type=="dir-c"' dir-c></tr>
  </tbody>
</table>

This way due to ng-if only the correct row will ever be displayed but the problem is that tbody will be repeated as many row as there are in data. But until there is a beter solution this is how I did it.

Upvotes: 0

segFault
segFault

Reputation: 4054

You could potentially use an ngSwitch here.

Plnkr

HTML

<div ng-repeat="(key, d) in data track by $index">
  <div class="tbody" ng-switch on="d.type">
    <div class="row" ng-switch-when="dir-b" dir-b>{{d}}</div>
    <div class="row" ng-switch-when="dir-c" dir-c>{{d}}</div>
  </div>
</div> 

Then you just define dirB and dirC directives.

This doesn't display as an html table though, you can hopefully work from this though?

Upvotes: 0

Related Questions