javascriptangularjsangularjs-directiveangularjs-ng-repeat

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?


Solution

  • 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.