Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular component which is two rows that will be added to another table

Tags:

angular

I am creating a component "template" (I think that's the right word) which can be either two rows

@Componenet({
  selector: '[my-row]',
  template: `
  <tr>
    <td>first</td>
    <td>second</td>
  </tr>
  <tr *ngIf="secondRow">
    <td>foo</td>
    <td>bar</td>
  </tr>`
})
export class MyRowComponent {
  @Input() secondRow = false;
}

I want to use this in another component like this

<table>
  <element my-row></element>
  <element my-row secondRow="true"></element>
  <element my-row></element>
  <element my-row></element>
</table>

But I am not sure what "element" should be.

If I just wanted one row, I could remove the "tr" from the MyRowComponenet, and just make it <tr my-row></tr>, but since I want two rows, this doesn't seem to be possible. <tbody> is not an option since I can only have one of those in a table.

I tried using <ng-component> and <ng-template> but I got obscure errors when using them.

Using divs instead of a table is not desired for my use case.

Can anyone help me out?

EDIT: Note that making element be tr does not work. Since it just creates a table inside the first cell of the table you are trying to create. Here is two components that demonstrate this.

import { Component, Input } from '@angular/core';

@Component({
  selector: '[my-row]',
  template: `
  <tr>
    <td>{{ firstWord }}</td>
    <td>{{ secondWord }}</td>
  </tr>
  <tr *ngIf="secondRow">
    <td>fooooooooooooooo</td>
    <td>bar</td>
  </tr>
  `
})
export class MyRowComponent {
  @Input() firstWord = 'first';
  @Input() secondWord = 'second';
  @Input() secondRow = false;
}

and the TableComponent that uses the rows.

import { Component } from '@angular/core';

@Component({
  selector: 'my-table',
  template: `
  <table class="table">
    <tr>
      <td>column 1</td>
      <td>column 2</td>
    </tr>
    <tr my-row firstWord="hello world" secondWord="good bye">
    <tr my-row secondRow="true">
    <tr my-row>
  </table>`
})
export class MyTableComponent {}

enter image description here

like image 970
zrbecker Avatar asked Oct 18 '22 07:10

zrbecker


1 Answers

My suggestion is having component like:

@Component({
  selector: 'tr[my-row]',
  template: `
    <td>{{ firstWord }}</td>
    <td>{{ secondWord }}</td>

    <ng-template #secondRow>
      <tr>
        <td>fooooooooooooooo</td>
        <td>bar</td>
      </tr>
    </ng-template>
  `
})
export class MyRowComponent {
  @Input() firstWord = 'first';
  @Input() secondWord = 'second';
  @Input() secondRow = false;

  @ViewChild('secondRow') template: TemplateRef<any>;

  constructor(private vcRef: ViewContainerRef) {}

  ngOnInit() {
    if(this.secondRow) {
      this.vcRef.createEmbeddedView(this.template);
    }
  }
}

parent.html

<table class="table">
  <tr>
    <td>column 1</td>
    <td>column 2</td>
  </tr>
  <tr my-row firstWord="hello world" secondWord="good bye">
  <tr my-row secondRow="true">
  <tr my-row>
</table>

Plunker Example

like image 186
yurzui Avatar answered Oct 20 '22 16:10

yurzui