Dans mon Angular 6, je dois passer un composant à un autre composant en tant que ng-template .
La raison en est que j'ai un composant A que je dois répliquer plusieurs fois, mais à chaque fois il doit inclure différents composants (appelons-les Composant B et Composant C ) qui ont les mêmes entrées .
Modèle du composant 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>
Et je crée une instance du composant A en utilisant:
<app-component-a
[entity]="row"
[entityName]="entityName"
></app-component-a>
J'ai donc pensé à utiliser ng-template
, modifiant ainsi le modèle du composant A comme suit:
<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>
Et en créant une instance A du composant A en utilisant:
<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>
Je peux donc facilement injecter Composant C au lieu de Composant B comme ng-template du composant 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>
Problème [~ # ~] [~ # ~] :
la variable form
que je dois injecter dans Composant B ou Composant C n'existe qu'à l'intérieur du composant A et pas dans Parent du composant A (pour certaines raisons, je ne peux pas le déplacer d'un niveau vers le haut).
Comment puis-je résoudre ce problème?
Avez-vous essayé en faisant simplement:
<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>
Pour que cela fonctionne, le membre form
défini dans le composant A doit être public, et de préférence readonly
.
Voici ce que vous pouvez faire:
Lorsque vous appelez le composant A, vous passez un modèle ng à celui-ci comme suit:
<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>
Maintenant, dans votre app-component-a.ts, vous procédez comme suit:
@ContentChild(TemplateRef) template: TemplateRef;
Donc, fondamentalement, le modèle obtiendra le composant b ou c en fonction de votre état.
Et puis dans le modèle de composant A, vous procédez comme suit:
<ng-container [ngTemplateOutlet]="template"></ng-container>
Alors maintenant, votre conteneur ng recevra le composant B ou C en fonction de votre état.
En ce qui concerne votre formulaire, je crains que la seule chose à laquelle je puisse penser est de créer un service et de le fournir dans le composant A, de l'injecter dans A, B et C et de partager le formulaire dans ce service.
Mais si vous incluez les composants B et C comme je l'ai montré ci-dessus, Angular gérera seul la création et la destruction de vos composants B et C.
Sinon, lorsque votre condition ng-template change, votre composant B ne sera pas détruit lorsque le composant C est instancié.
Modifier:
Une autre chose à laquelle je peux penser est que si vous n'appelez pas le composant B ou C dès que A est instancié, vous pouvez également émettre la forme (@Output) de A vers le parent de A sur Ainit de A. De cette façon, lorsque B ou C est appelé, le parent de A aura accès au formulaire et il pourra le transmettre à B ou C.