Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular pass a Component as ng-template of another Component

In my Angular 6 app I need to pass a Component to another Component as its ng-template.

The reason is that I have a Component A that I need to replicate many times, but each time it has to include different components (let's call them Component B and Component C) which have the same Inputs.

Component A template:

<div class="row-detail-panel">
  <h4 class="row-detail-panel-title">{{ newEntity ? 'Add new' : 'Edit this'}} {{ entityName }}</h4>

  <!--THIS IS THE COMPONENT I WANT TO INJECT-->
  <app-component-b
    [inline]="true"
    [form]="form"
  ></app-component-b>
  <!--END-->

  <!--some more html code here-->
</div>

And I create a Component A instance using:

<app-component-a
  [entity]="row"
  [entityName]="entityName"
></app-component-a>

So I thought about using ng-template, so changing the Component A template as follows:

<div class="row-detail-panel">
  <h4 class="row-detail-panel-title">{{ newEntity ? 'Add new' : 'Edit this'}} {{ entityName }}</h4>

  <ng-template></ng-template>

  <!--some more html code here-->
</div>

And creating a Component A instance using:

<app-component-a
  [entity]="row"
  [entityName]="entityName"
>
  <app-component-b
    [inline]="true"
    [form]="form" <!--PROBLEM: "form" does not exist here-->
  ></app-component-b>
</app-component-a>

So I can easily inject Component C instead of Component B as Component A's ng-template:

<app-component-a
  [entity]="row"
  [entityName]="entityName"
>
  <app-component-c
    [inline]="true"
    [form]="form" <!--PROBLEM: "form" does not exist here-->
  ></app-component-c>
</app-component-a>

PROBLEM:

the variable form that I need to inject to Component B or Component C exists only inside Component A and not in Component A's parent (for some reasons I cannot move it one level up).

How can I solve this problem?

like image 387
Francesco Borzi Avatar asked Jul 04 '18 10:07

Francesco Borzi


1 Answers

Have you tried by simply doing:

<app-component-a #compA
  [entity]="row"
  [entityName]="entityName">
  <app-component-b
    [inline]="true"
    [form]="compA.form"
  ></app-component-b>
</app-component-a>

// component-a.html

<div class="row-detail-panel">
  <h4 class="row-detail-panel-title">{{ newEntity ? 'Add new' : 'Edit this'}} {{ entityName }}</h4>
  <ng-content></ng-content>
</div>

In order for this to work, the form member defined in the A component should be public, and preferably readonly.

like image 176
Jota.Toledo Avatar answered Sep 23 '22 11:09

Jota.Toledo