DennyHiu DennyHiu - 16 days ago 5
AngularJS Question

How to include <tr> element in angular directive (transclude)?

I want to include

<tr>
and
<td>
and apparently I can't do that with directive. It keeps ignoring
<td>
or
<td>
as if they don't exists. here's what I trying to accomplish:

<my-table>
<tr>
<td>hello</td>
<td>world</td>
</tr>
</my-table>


Here's the javascript:

angular.module('app', [])
.controller('Controller', ['$scope', function($scope) {

}])
.directive('myTable', function() {
return {
restrict: 'E',
transclude: true,
templateUrl: 'my-table.html'
};
});


my-table.html :

<table ng-transclude>

</table>


the code above resulted in:

<my-table class="ng-isolate-scope"><table ng-transclude="">

hello <-- no <tr> nor <td> here just plain text
world

</table></my-table>


example : PLUNKR

Answer

It's not a transclude problem. It's a problem with invalid html, because <tr> without a table is invalid. So angular gets from a browser text, not DOM elements. So you need to have <table> tag inside an html:

  <my-table>
  <table>
      <tr>
       <td>hello</td>
       <td>world</td>
     </tr>
  </table>
  </my-table>

Then you'll be able to get access to tbody element created by a browser along with tr's in link function and process it:

  link: function(scope,element,attrs,ctrls,transclude) {
    var html = transclude();
    element.find('table').append(html[1].firstElementChild);
  }

or use ng-transclude in your template as you did. However, I may presume that you'll want to reuse the transcluded part later, so accessing it in link function makes more sense to me.