27

I have a table in which I want to display a table row, which is a component. And also I want to pass data to that component:

<table>
    <th>
        <td>col 1</td>
        <td>col 2</td>
        <td>col 3</td>
    </th>
    <tr>
        <my-component [data1]="data1" [data2]="data2"></my-component>
    </tr>
    <tr *ngFor="let item of list">
        {{item}}
    </tr>
</table>

In my-component, the HTML is a few <td></td> with data rendered from data1 and data2.

But after rendering it, because of <my-component></my-component> my CSS is breaking resulting in all my-component HTML (whole table row) displaying in 1st column.

Result of above:

<table>
    <th>
        <td>col 1</td>
        <td>col 2</td>
        <td>col 3</td>
    </th>
    <tr>
        <my-component>
            <td>data1.prop1</td>
            <td>data1.prop2</td>
        </my-component>
    </tr>
    <tr *ngFor="let item of list">
        {{item}}
    </tr>
</table>

I tried the following:

@Component({
    selector: '[my-component]',
    templateUrl: 'my-component.html'
})

<tr my-component [data1]="data1" [data2]="data2"></tr>

But this results in error Can't bind to 'data1' since it isn't a known property of 'tr'.

Also I can not use @Directive as I want to render HTML.

How can I render template of <my-component></my-component> without <my-component></my-component> tag?

Other answers are of previous versions of angular. I am using Angular 4.3.4.

Any help would be appreciated..!

Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84
AjinkyaBhagwat
  • 683
  • 2
  • 6
  • 18
  • If you are able to setup a Codepen or similar with a working example of your application, we would have a much better chance at helping you. – M0nst3R Oct 10 '17 at 16:22
  • selector: '[my-component]' was correct. You just forgot to write Input data1 and Input data2. – omeralper Oct 10 '17 at 22:09
  • It sounds like your CSS rules may be overly specific. – Aluan Haddad Oct 11 '17 at 01:11
  • @omeralper I have added @Input() for data 1 and data 2, It's working fine if I use but because of those tags css was breaking , hence I tried with tr tag. – AjinkyaBhagwat Oct 11 '17 at 04:35
  • @AluanHaddad I have used bootstrap, it's bootstrap's css for td which was breaking. – AjinkyaBhagwat Oct 11 '17 at 04:36
  • @GhassenLouhaichi thanks for suggestion ! – AjinkyaBhagwat Oct 11 '17 at 04:43
  • I found [this answer](https://stackoverflow.com/a/56887630/4172413) on [this related question](https://stackoverflow.com/questions/38716105/angular2-render-a-component-without-its-wrapping-tag) to be very helpful. It allows you to unwrap the component. Also the related comments are useful to implement it. – Brian Davis Jun 10 '22 at 15:01

1 Answers1

22

you need to include tr as well in selector like below,

@Component({
 selector: 'tr[my-component]',
 template: `
   <td>{{data1.prop1}}</td>
   <td>{{data1.prop2}}</td>
   <td>{{data2.prop1}}</td>
 `
})
export class MyComponent {
  @Input() data1;
  @Input() data2;
}

Check this Plunker!!

Madhu Ranjan
  • 17,334
  • 7
  • 60
  • 69
  • 3
    No, you don't have to include 'tr' as well. Remove 'tr' and try, it is gonna work. – omeralper Oct 10 '17 at 22:10
  • 7
    But you should include the `tr` in the selector since this is only intended to be used on trs, where else would you add a td? Makes your intention clear and prevents mistakes. Just because it works, it doesn't mean you should do it – Ruan Mendes Aug 02 '19 at 11:37
  • 1
    This is like a directive. Not really unwrapped. But a workaround for some issues. A real unwrapped component should work like the pseudo component `ng-container` or `ng-template`. Sadly no solution found yet. For some cases it's really important to have components without its own tag to reuse code without break the selectors of parents (e.g. 3rd party frameworks). e.g. if you have multiple elements and you can't wrap it. Also this solution (attribute selector) will not work for such issue. ... – Domske May 14 '20 at 10:00
  • 1
    Another reason to add the `tr` is that if you dynamically create a component (eg. with ComponentPortal it will be able to create it correctly with the right tag). – Simon_Weaver Jul 13 '20 at 23:08