Q:

Angular Child binding and transclusion

Using Angular, I would like to do some
<my-table-component [Items]="Items">
  <my-column-component Title="The Id">
    {{Item.Id}}
  </my-column-component>
  <my-column-component Title="The Name">
    <span>{{Item.Name}}</span>
  </my-column-component>
  <my-column-component Title="The Avatar">
    <img [src]="Item.Picture" />
  </my-column-component>
</my-table-component>

The issue is that I don't want the content of each column to be rendered right here and right now.
Giving the Items contains array of object like:
Items = [
  { Id: 1, Name: "I'm One", Picture: "/picture/1.jpg" },
  { Id: 2, Name: "I'm Two", Picture: "/picture/2.jpg" },
  { Id: 3, Name: "I'm Three", Picture: "/picture/3.jpg" },
]

The end result I want would be something like
<div class="my-table-component">
  <div class="my-table-component-header">
    <div class="my-table-component-header-item">The Id</div>
    <div class="my-table-component-header-item">The Name</div>
    <div class="my-table-component-header-item">The Name</div>
  </div>
  <div class="my-table-component-content">
    <div class="my-table-component-content-item">1</div>
    <div class="my-table-component-content-item"><span>I'm One</span></div>
    <div class="my-table-component-content-item"><img [src]="/picture/1.jpg" /></div>
  </div>
  <div class="my-table-component-content">
    <div class="my-table-component-content-item">2</div>
    <div class="my-table-component-content-item"><span>I'm Two</span></div>
    <div class="my-table-component-content-item"><img [src]="/picture/2.jpg" /></div>
  </div>
  <div class="my-table-component-content">
    <div class="my-table-component-content-item">3</div>
    <div class="my-table-component-content-item"><span>I'm Three</span></div>
    <div class="my-table-component-content-item"><img [src]="/picture/3.jpg" /></div>
  </div>
</div>

So the binding of each column is not made directly here it is declared, but dynamicly, for each Item of the table component bound Items.
I've try things using NgTemplateOutlet, but or I don't understand well how it works, or it's not what I'm looking for.

A:

Here's a solution that uses structural directives and NgTemplateOutlet to achieve the result you want. See this StackBlitz link for the full code.
Usage
Starting HTML:
(app.component.html)
<my-table-component [Items]="Items">
    <my-column-component>
        <my-cell *columnHeader>The Id</my-cell>
        <my-cell *columnCells="let Item">{{Item.Id}}</my-cell>
    </my-column-component>
    <my-column-component>
        <my-cell *columnHeader>The Name</my-cell>
        <my-cell *columnCells="let Item"><span>{{Item.Name}}</span></my-cell>
    </my-column-component>
    <my-column-component>
        <my-cell *columnHeader>The Avatar</my-cell>
        <my-cell *columnCells="let Item"><img src="{{Item.Picture}}" /></my-cell>
    </my-column-component>
</my-table-component>

Notes:

Use the *columnHeader and *columnCells structural directives to denote which cells you want to become the column headers and regular table cells respectively
To use data binding (e.g. <span>{{Item.Name}}</span>) in the table cells, set *columnCells="let myVarHere" (e.g. *columnCells="let Item") to declare the iteration variable that you want to use.

End result:
<div class="my-table-component">
   <div class="my-table-component-header">
      <div class="my-table-component-header-item"><my-cell>The Id</my-cell></div>
      <div class="my-table-component-header-item"><my-cell>The Name</my-cell></div>
      <div class="my-table-component-header-item"><my-cell>The Avatar</my-cell></div>
   </div>
   <div class="my-table-component-content">
      <div class="my-table-component-content-item"><my-cell>1</my-cell></div>
      <div class="my-table-component-content-item"><my-cell><span>I'm One</span></my-cell></div>
      <div class="my-table-component-content-item"><my-cell><img src="/picture/1.jpg" /></my-cell></div>
   </div>
   <div class="my-table-component-content">
      <div class="my-table-component-content-item"><my-cell>2</my-cell></div>
      <div class="my-table-component-content-item"><my-cell><span>I'm Two</span></my-cell></div>
      <div class="my-table-component-content-item"><my-cell><img src="/picture/2.jpg" /></my-cell></div>
   </div>
   <div class="my-table-component-content">
      <div class="my-table-component-content-item"><my-cell>3</my-cell></div>
      <div class="my-table-component-content-item"><my-cell><span>I'm Three</span></my-cell></div>
      <div class="my-table-component-content-item"><my-cell><img src="/picture/3.jpg" /></my-cell></div>
   </div>
</div>

Angular code:
(app.component.ts)
export class AppComponent {
  Items = [
    { Id: 1, Name: "I'm One", Picture: "/picture/1.jpg" },
    { Id: 2, Name: "I'm Two", Picture: "/picture/2.jpg" },
    { Id: 3, Name: "I'm Three", Picture: "/picture/3.jpg" },
  ];
}

(my-table-components.component.ts - I chose to put all the "table"-related components/directives in one file but you can split this into multiple files if you want)
import { Component, Directive, Input, TemplateRef } from '@angular/core';

@Directive({ selector: 'my-column-component' })
class MyColumnComponent { }

@Directive({ selector: 'my-cell' })
class MyCell { }

@Component({
  selector: 'my-table-component',
  template: `
  <div class="my-table-component">
    <div class="my-table-component-header">
      <div class="my-table-component-header-item" *ngFor="let header of columnHeaders">
        <ng-container *ngTemplateOutlet="header; context: {$implicit:Item}"></ng-container>
      </div>
    </div>

    <div class="my-table-component-content" *ngFor="let Item of Items">
      <div class="my-table-component-content-item" *ngFor="let cell of columnCells">
        <ng-container *ngTemplateOutlet="cell; context: {$implicit: Item}"></ng-container>
      </div>
    </div>
  </div>
  `,
  styles: []
})
class MyTableComponent {
  @Input() Items: Object[];

  columnHeaders: TemplateRef<void>[] = [];
  columnCells: TemplateRef<void>[] = [];
}

// Structural directives

@Directive({ selector: '[columnHeader]'})
class ColumnHeader {
  constructor(templateRef: TemplateRef<void>, table: MyTableComponent) {
    table.columnHeaders.push(templateRef);
  }
}

@Directive({ selector: '[columnCells]'})
class ColumnCell {
  constructor(templateRef: TemplateRef<void>, table: MyTableComponent) {
    table.columnCells.push(templateRef);
  }
}

export { MyTableComponent, MyCell, MyColumnComponent, ColumnHeader, ColumnCell }

Explanation
In the starting HTML, you have something like this to represent each column:
<my-column-component>
   <my-cell *columnHeader>The Id</my-cell>
   <my-cell *columnCells="let Item">{{Item.Id}}</my-cell>
</my-column-component>

Notice that we are putting an asterisk * prefix in front of the columnHeader and columnCells directives. This tells Angular that we want to use the directives as structural directives. (A structural directive is a directive that changes the DOM structure, such as by adding, removing, or manipulating elements. For example, *ngIf and *ngFor are structural directives.)
Internally, Angular de-sugarizes the asterisk syntax by wrapping an <ng-template> tag around the original element. For example, this:
<my-cell *columnHeader>The Id</my-cell>
<my-cell *columnCells="let Item">{{Item.Id}}</my-cell>

would be converted into this:
<ng-template columnHeader>
   <my-cell>The Id</my-cell>
</ng-template>
<ng-template columnCells let-Item>
   <my-cell>{{Item.Id}}</my-cell>
</ng-template>

So each element with the *columnHeader or *columnCells directive would be wrapped around with an <ng-template> element. Since they're each inside an <ng-template>, we can Angular's TemplateRef to get a reference to the <ng-template> element, and then pass the reference into MyTableComponent to be displayed using *ngTemplateOutlet.
Have a look at this diagram here to see what I mean.
Example:
@Directive({ selector: '[columnCells]'})
class ColumnCell {
  constructor(templateRef: TemplateRef<void>, table: MyTableComponent) {
    table.columnCells.push(templateRef);
  }
}

--
<div class="my-table-component">
  <div class="my-table-component-header">
    <div class="my-table-component-header-item" *ngFor="let header of columnHeaders">
      <ng-container *ngTemplateOutlet="header; context: {$implicit:Item}"></ng-container>
    </div>
  </div>

  <div class="my-table-component-content" *ngFor="let Item of Items">
    <div class="my-table-component-content-item" *ngFor="let cell of columnCells">
      <ng-container *ngTemplateOutlet="cell; context: {$implicit: Item}"></ng-container>
    </div>
  </div>
</div>

I recommend taking a look at this excellent video to get a better understanding of structural directives and NgTemplateOutlet, as well as the code example in the Angular docs for NgTemplateOutlet.

