Saqib Ali Saqib Ali - 2 months ago 11
AngularJS Question

AngularJS error: Template for directive 'XXXXXX' must have exactly one root element

This is a follow-up to this question.

I am trying to build and HTML

<table>
with multiple
<tr>
rows. I want some of these rows to be rendered by my directive
myDirectiveA
and others to be rendered by my directive 'myDirectiveB'.

Below you can see what my files look like. It all works fine if there is only one
<tr>
row in the file
path/to/myDirectiveA.template.html
. But as soon as I add another row in there, I get the following error:

`angular.js:13920 Error: [$compile:tplrt] Template for directive 'myDirectiveA' must have exactly one root element. path/to/myDirectiveA.template.html`


Ok, so if I am allowed only to have one root element in that template file, then how can I construct my table with multiple rows from various directives? What is the way other people solve this seemingly-common use-case?

Here are my files:

main.html:

<div ng-controller="MainCtrl as mainCtrl">
<table width="40%" border="1">
<tbody>
<tr my-directive-a a="mainCtrl.a"></tr>
</tbody>
</table>
</div>


app.js:

myApp.directive('myDirectiveA',function(){
return {
'replace': true,
'restrict': 'A',
'scope': {
'a': '='
},
'controller': 'MyDirectiveACtrl',
'controllerAs': 'MyDirectiveACtrl',
'bindToController': true,
'templateUrl': "path/to/myDirectiveA.template.html"
};
});


myApp.controller('MyDirectiveACtrl', function($scope){
var self = this;
$scope.$watch(function() {return {'a': self.a};}, function (objVal) {},true);
}
);


path/to/myDirectiveA.template.html:

<tr>
<td bgcolor='#7cfc00'>MyDirectiveACtrl.a.b</td>
<td bgcolor='#ff1493'>{{MyDirectiveACtrl.a.b}}</td>
</tr>

Answer

Use this in the app

<table width="40%" border="1">
  <tbody  my-directive-a a="mainCtrl.a">
  </tbody>
</table>

and this in the directive template

<tbody>
<tr>
    <td bgcolor='#7cfc00'>MyDirectiveACtrl.a.b</td>
    <td bgcolor='#ff1493'>{{MyDirectiveACtrl.a.b}}</td>
</tr>
<tr>
    <td bgcolor='#7cfc00'>MyDirectiveACtrl.a.b</td>
    <td bgcolor='#ff1493'>{{MyDirectiveACtrl.a.b}}</td>
</tr>
</tbody>

It allows you to have only one root element in your directive, and add more than one TR inside of it.