Home > Back-end >  Angular embed view as peer to current component
Angular embed view as peer to current component

Time:12-12

I'm wanting to do this in my HTML:

<tr *ngFor="let row of rows">
    <expandable-tree-row [columns]="cols" [data]="row"></expandable-tree-row>
</tr>

In the ExpandableTreeRowComponent I used a ViewContainerRef so that the td tags are placed as a direct child of the tr element, like so:

constructor(public readonly container: ViewContainerRef, private readonly cdr: ChangeDetectorRef) {
}

ngAfterViewInit(): void {
    this.columns.forEach(x => this.container.createEmbeddedView(x.template))
    this.cdr.detectChanges()
}

That's adding each column's template properly, and in the correct location. But now I still have the problem that the very first child of the tr element is the empty <expandable-tree-row> and so that messes up the table output by essentially shifting all of the columns one to the right.

How do I get rid of that first "bad" element now?

If instead I make it a directive and place on the tr element, like so:

<tr expandable-tree-row [columns]="cols"></tr>

then visually it looks right, but the generated HTML technically is wrong as it ends up like this:

<tr>...</tr>
<td>...</td>
<td>...</td>
<tr>...</tr>
<td>...</td>
<td>...</td>

In other words, the td elements aren't children of the tr elements.

CodePudding user response:

If you use the attribute selector option <tr expandable-tree-row [columns]="cols"></tr> You just need some adjustments: instead of injecting ViewContainerRef in your constructor, put in your expandable-tree-row template an ng-template with a template variable named container like:

<ng-template #container></ng-template>

And query it as ViewContainerRef with @ViewChild like:

@ViewChild('container', { read: ViewContainerRef })
  private container: ViewContainerRef;
  • Related