Ricardo Mota Ricardo Mota - 3 months ago 9
AngularJS Question

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 completetly diferent 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 wich 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?

Answer

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.