Child doesn't render template passed by parent

Issue

Well, this is my parent component where I am trying to pass the template nodeTemplate to the child ils-tree

<div class="nodes-panel">
    <ils-tree layout="horizontal" [json]="nodes" [template]="nodeTemplate">
    </ils-tree>
</div>

<ng-template #nodeTemplate>
    <ng-template let-node  pTemplate="default">
        <p class="node-type">{{node.data.nodeType}}</p>
        <p class="node-name">{{node.data.name}}</p>
    </ng-template>
    <ng-template let-node  pTemplate="orgNode">
        <p class="org-node-name">{{node.data.name}}</p>
    </ng-template>
</ng-template>

The child component ils-tree‘s HTML looks this way

<p-tree
  [value]="nodes"
  [layout]="layout"
  selectionMode="single"
  [(selection)]="selectedNode"
  [loading]="loading"
>
  <ng-container *ngTemplateOutlet="template"></ng-container>
</p-tree>

and the controller file has

@Input()
template: TemplateRef<any>;

Basically, the ps are nowhere to be seen and yes, the data json is being passed successfully. Help!

P.S The template when embedded directly, in between, works.
That is,

<p-tree
  [value]="nodes"
  [layout]="layout"
  selectionMode="single"
  [(selection)]="selectedNode"
  [loading]="loading"
>
  <ng-template let-node  pTemplate="default">
        <p class="node-type">{{node.data.nodeType}}</p>
        <p class="node-name">{{node.data.name}}</p>
    </ng-template>
    <ng-template let-node  pTemplate="orgNode">
        <p class="org-node-name">{{node.data.name}}</p>
    </ng-template>
</p-tree>

Solution

I think primeng tree doesn’t let you use a template inside another templates with the pTemplate correct.

I could make a workaround declaring the templates separated and passing the type too.
The main page would look like:

<ils-tree [templates]="[{type:'orgNode',template:templateOrg},
{type:'default',template:templateDefault}]"
 [data]="data"></ils-tree>

<ng-template let-node="node" pTemplate="default" #templateDefault>
    <p class="node-type">{{node.label}}</p>
</ng-template>

<ng-template let-node="node" pTemplate="orgNode" #templateOrg>
    <p class="org-node-name">{{node.label}}</p>
</ng-template>

Then the ils-tree.html would look like:

<p-tree [value]="data">
    <ng-container *ngFor="let temp of templates">
    <ng-template [pTemplate]="temp.type" let-node>
        <ng-template [ngTemplateOutlet]="temp.template" [ngTemplateOutletContext]="{
                 node:node
               }">
            </ng-template>
        </ng-template>
    </ng-container>
</p-tree>

The trick here is passing the node you are using as a context with ngTemplateOutletContext to your template so you can use it in the main with the let-node=”node”.

The ils-tree.ts would look like:

  @Input() templates: any[];
  @Input() data: any;

In my example I added a model for the templates to make it more easy to read.

You have the live example here:
https://stackblitz.com/edit/angular-tree-templates

Answered By – Daniel Piñeiro

Answer Checked By – Willingham (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.