Угловая передача компонента в качестве ng-шаблона другого компонента - PullRequest
0 голосов
/ 04 июля 2018

В моем приложении Angular 6 мне нужно передать Компонент другому Компоненту как его ng-template .

Причина в том, что у меня есть Компонент A , который мне нужно копировать много раз, но каждый раз, когда он должен включать в себя различные компоненты (назовем их Компонент B и Компонент C ), который имеет одинаковые входы .

Компонент A шаблон:

<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>

И я создаю экземпляр Component A , используя:

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

Итак, я подумал об использовании ng-template, поэтому изменил шаблон Component A следующим образом:

<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>

И создание экземпляра компонента A с использованием:

<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>

Так что я могу легко ввести Компонент C вместо Компонент B как NG-шаблон компонента A :

<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>

ПРОБЛЕМА

переменная form, которую мне нужно ввести в Компонент B или Компонент C существует только внутри Компонент A и не в родительском компоненте A (по некоторым причинам я не могу переместить его на один уровень вверх).

Как я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Вы пробовали, просто делая:

<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>

Для того, чтобы это работало, элемент form, определенный в компоненте A, должен быть открытым, предпочтительно readonly.

0 голосов
/ 04 июля 2018

Что вы можете сделать, это:

Когда вы вызываете компонент A, вы передаете ему шаблон ng следующим образом:

<app-component-a> 
   <ng-template *ngIf=”condition; else elseBlock”> 
      <app-component-b></app-component-b> 
   </ng-template> 
   <ng-template #elseBlock> 
      <app-component-c></app-component-c> 
   </ng-template>
</app-component-a> 

Теперь в вашем app-component-a.ts вы делаете это:

@ContentChild(TemplateRef) template: TemplateRef;

Таким образом, в основном шаблон получит компонент b или c в зависимости от вашего состояния.

И затем в компоненте A вы делаете это:

<ng-container [ngTemplateOutlet]="template"></ng-container>

Так что теперь ваш ng-контейнер получит Компонент B или C в зависимости от вашего состояния.

Что касается вашей формы, я боюсь, что единственное, о чем я могу думать, - это создать сервис и предоставить его в компоненте A, внедрить его в A, B и C и поделиться формой в этом сервисе.

Но если вы включите компоненты B и C, как я показал выше, Angular самостоятельно обработает создание и уничтожение ваших компонентов B и C.

В противном случае при изменении условия вашего ng-шаблона ваш компонент B не будет уничтожен при создании экземпляра компонента C.

Edit:

Еще одна вещь, о которой я могу подумать, это то, что, если вы не вызываете компонент B или C, как только создается экземпляр A, вы также можете передать (@Output) форму из A в родительский oninit A. Это так, когда B или вызывается C, родитель A будет иметь доступ к форме и может передать ее B или C.

...