14

在我的 Angular 6 应用程序中,我需要将 Component 作为其ng-template传递给另一个 Component 。

原因是我有一个Component A需要多次复制,但每次它都必须包含具有相同 Inputs的不同组件(我们称它们为Component BComponent 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>

我使用以下方法创建了一个组件 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>

因此,我可以轻松地将Component C而不是Component B作为Component A的 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>

问题

form我需要注入到组件 B组件 C的变量仅存在于组件 A内部,而不存在于组件 A 的父组件中(由于某些原因,我无法将其上移一级)。

我怎么解决这个问题?

4

2 回答 2

8

你可以做的是:

当您调用组件 A 时,您将 ng-template 传递给它,如下所示:

<app-component-a> 
   <ng-template *ngIf=”condition; else elseBlock”&gt; 
      <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-container 将根据您的情况获得组件 B 或 C。

就您的表单而言,恐怕我唯一能想到的就是创建一个服务并在组件 A 中提供它,将其注入 A、B 和 C 并在该服务中共享表单。

但是如果你按照我上面展示的方式包含组件 B 和 C,Angular 将自行处理 B 和 C 组件的创建和销毁。

否则,当您的 ng-template 条件发生变化时,您的组件 B 在组件 C 实例化时不会被销毁。

编辑:

我能想到的另一件事是,如果您在实例化 A 时不调用组件 B 或 C,您还可以从 A 向 A 的父 oninit 发出 (@Output) 表单。当 B 或 C 为调用时,A 的父级将有权访问表单,并且可以将其传递给 B 或 C。

于 2018-07-04T10:42:32.503 回答
8

您是否尝试过简单地执行以下操作:

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

于 2018-07-04T11:05:37.533 回答