Multi slot content projection in angular doesn't work with component

1.3k views Asked by At

I'm trying to create a component that takes some divs and places them in a specific order depending on the classes defined in the content to project. For this, I've created a component with some ng-content elements with class selectors. It does works if I pass some static HTML, however, if I pass a component it doesn't show anything (except if I use a single slot). I've created an example in StackBlitz that can be found here.

I've defined three different scenarios using the same component:

  1. Passing static HTML and configuring the component to use multiple slots, everything works fine.
    <app-content-formatter>
      <div class="body">This is just a nonsense text</div>
      <div class="head">This is the head.... I guess</div>
    </app-content-formatter>
    
  2. Passing another component and configuring it to use multiple slots, nothing gets rendered
    <app-content-formatter>
      <app-some-text></app-some-text>
    </app-content-formatter>
    
  3. Passing another component and configuring it to use a single slot, everything works (however, the elements are not displayed as it's required)
    <app-content-formatter [multiSlot]="false">
      <app-some-text></app-some-text>
    </app-content-formatter>
    

I'm not sure why this is happening, and there's a huge chance I may have forgotten something (I've started working with angular a few months ago). The sample provided in StackBlitz it's an abstraction of a more complex scenario that requires replacing a component that is used in a big application, the idea is to avoid a lot of changes by reusing the existing classes and structure, that's the reason I'd like to use the content projection.

If I have to guess, I'd say the problem is the selectors, they might change since they're inside a tag with the name of the component itself, which could be a problem as well, as we need to display different controls which will be loaded dynamically (that part was not included in the example since the problem is the content projection).

Thank you everyone in advance for all your help!

2

There are 2 answers

0
GeekerMode On

Jhon - to expand on Monkey MKU answer, multi-slot projection inserts content where the selectors match - that means it is independent of your ngIf.

See StackBlitz example here.

0
Monkey MKU On

You defined a class selector so the component you want to project needs to use the class of your selector.

<app-some-text class="head"></app-some-text>

Afaik there is no way to project the actual content of the component in different slots. You would need to separate that in different components and project each component with the appropriate selector.