I am struggling to find a way to do this. In a parent component, the template describes a table
and its thead
element, but delegates rendering the tbody
to another component, like this:
<table> <thead> <tr> <th>Name</th> <th>Time</th> </tr> </thead> <tbody *ngFor="let entry of getEntries()"> <my-result [entry]="entry"></my-result> </tbody> </table>
Each myResult component renders its own tr
tag, basically like so:
<tr> <td>{{ entry.name }}</td> <td>{{ entry.time }}</td> </tr>
The reason I’m not putting this directly in the parent component (avoiding the need for a myResult component) is that the myResult component is actually more complicated than shown here, so I want to put its behaviour in a separate component and file.
The resulting DOM looks bad. I believe this is because it is invalid, as tbody
can only contain tr
elements (see MDN), but my generated (simplified) DOM is :
<table> <thead> <tr> <th>Name</th> <th>Time</th> </tr> </thead> <tbody> <my-result> <tr> <td>Bob</td> <td>128</td> </tr> </my-result> </tbody> <tbody> <my-result> <tr> <td>Lisa</td> <td>333</td> </tr> </my-result> </tbody> </table>
Is there any way we can get the same thing rendered, but without the wrapping <my-result>
tag, and while still using a component to be sole responsible for rendering a table row ?
I have looked at ng-content
, DynamicComponentLoader
, the ViewContainerRef
, but they don’t seem to provide a solution to this as far as I can see.
Advertisement
Answer
You can use attribute selectors
@Component({ selector: '[myTd]' ... })
and then use it like
<td myTd></td>