I am trying to create a simple customizable modal. Where I can pass via Input() decorator a TemplateRefs and then my component would render that.
I am passing 2 TemplateRefs. 1 - The black backdrop, 2 - The dialog box. (I need the backdrop differently in other places in my app).
I am getting both inputs, and they work.** But they are created adjacent to each other, not nested.**
adjacent elements, not nested.
And without further adew, here it is...
<ng-container [ngTemplateOutlet]="backdropTemplate">
<ng-container [ngTemplateOutlet]="dialogTemplate"></ng-container>
</ng-container>
I created a codepen to better demonstrate: https://codesandbox.io/embed/elastic-morning-fnxgeb?fontsize=14&hidenavigation=1&theme=dark
I have come to ngTemplateOutlet so that I can make my modal component generic. However, if I can't nest the DialogBox template, inside the backdrop template then I would rather just pass both. But I would like to see what you think!
I have been going at this for a few hours now, tried to surround with this. ng-content instead..
The biggest problem with this is that you need to somehow tell angular where to put the inner template. One solution I can think of is to use the context of the background-template to pass the inner template and let it handle the second template outlet by itself. Let me show you what I mean.
Inside of the modal.component.html we do something like this:
<ng-container
*ngTemplateOutlet="backdropTemplate; context: { dialogTemplate: dialogTemplate}"
></ng-container>
This tells the *ngTemplateOutlet
directive to give the backdropTemplate
the additional context specified. The backdropTemplate
can now use this context like this:
<ng-template #modalBackdrop let-innerTemplate="dialogTemplate">
<div [ngClass]="{ 'modal-backdrop': true, 'backdrop-active': showModal }" (click)="toggleModal()">
<ng-container *ngTemplateOutlet="innerTemplate"></ng-container>
</div>
</ng-template>
So we essentially tell angular to bind the context variable dialogTemplate
to the local variable innerTemplate
and can use this to render it in another *ngTemplateOutlet
. This is a technique often used in structural directives. The closest example I could find for this in the documentation is here.