私のAngular 6アプリでは、コンポーネントを ng-template として別のコンポーネントに渡す必要があります。
理由は、何度も複製する必要があるComponent Aがありますが、そのたびに異なるコンポーネントを含める必要があるためです(それらをComponent 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>
そして、以下を使用してComponent 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 Bの代わりにComponent Cを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>
[〜#〜]問題[〜#〜]:
コンポーネントBまたはコンポーネントCに注入する必要がある変数form
は、コンポーネントAおよびnotinComponent Aのparent(何らかの理由で1レベル上に移動できません)。
この問題を解決するにはどうすればよいですか?
あなたは単純にやってみましたか:
<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>
これが機能するためには、Aコンポーネントで定義されているform
メンバーはパブリックである必要があり、できればreadonly
である必要があります。
あなたができることはこれです:
コンポーネント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-templateの条件が変更されても、コンポーネントCがインスタンス化されたときにコンポーネントBは破棄されません。
編集:
私が考えることができるもう1つのことは、Aがインスタンス化された直後にコンポーネントBまたはCを呼び出さない場合、AからAの親oninitに(@Output)フォームを発行することもできるということです。この方法はBまたはCが呼び出されると、Aの親はフォームにアクセスでき、BまたはCに渡すことができます。