Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transclude in Angular directive putting elements inside a single 'span'

Here is my directive:

myapp.directive('envtable',  function () {
return {
    restrict: 'E',
    replace: true,
    transclude: true,
    template: '<table class="table" ng-transclude></table>'
};
});

This is how i use it in html (using bootstrap css)

<envtable>
    <tr>
      <td>OS</td>
      <td>{{env.osName}}</td>
    </tr>
    <tr>
      <td>OS Version</td>
      <td>{{env.osVersion}}</td>
    </tr>
  </envtable>

However, the code generated looks like this in chrome:

<table class="table" ng-transclude=""><span class="ng-scope ng-binding">

      OS
      Windows 8


      OS Version
      6.2

  </span></table>

As you can see, Angular just ignored all my tr/td tags and put the contents in a single span element. Why is this happening?

Btw, as an experiment, i tried using just a transcluded p tag in the envtable instead of the tr\td tags and in that case angular just adds a ng-scope class to the p tag. So why does it screw up these tr/td tags?

like image 605
pdeva Avatar asked Aug 09 '13 23:08

pdeva


People also ask

What does transclude option of a directive do?

Transclude makes the contents of a directive with this option have access to the scope outside of the directive rather than inside.

What is transclude in AngularJS directive?

The ng-transclude directive facilitates AngularJS to capture everything that is put inside the directive in the markup and use it somewhere in the directive's template. Syntax: <ng-transclude.


2 Answers

It turns out this works with restrict: 'A'

<table envtable>
    <tr>
        <td>OS</td>
        <td>{{env.osName}}</td>
    </tr>
    <tr>
        <td>OS Version</td>
        <td>{{env.osVersion}}</td>
    </tr>
</table>

Demo

like image 151
zs2020 Avatar answered Oct 05 '22 11:10

zs2020


Just provide another example in case your table template has other elements like thead

Plunker

app.directive('envtable', function() {
  return {
    replace: true,
    transclude: true,
    template: '<table class="NewTable"><thead><th>Col1</th><th>Col2</th><th>Col3</th></thead></table>',
    link: function(scope, elem, attrs, controller, transcludeFn) {
      var item = transcludeFn(scope, function(clone) {
        return clone.children();
      });
      elem.append(item);
    }
  };
});


 <table envtable>
    <tbody>
      <tr ng-repeat='r in rows'>
        <td>{{r.col1}}</td>
        <td>{{r.col2}}</td>
        <td>{{r.col3}}</td>
      </tr>
    </tbody>
  </table>
like image 38
maxisam Avatar answered Oct 05 '22 11:10

maxisam