1

Is there a way to conditionally show slots in an angular template? I want to transclude content, if there is any, and show default content otherwise.

Let's say there's a my-card component, with a template like this:

<my-card>
  <ng-content select="[card-body]"></ng-content>
  <div *ngIf="!card-body">Default text</div>
</my-card>

Then the usage (in, say, app component) would be like this:

<!-- This will show the card body -->
<my-card><div card-body>This is card body</div></my-card>
<!-- This will show the default text -->
<my-card></my-card>

If this won't work with slots, what are my alternatives?

Zlatko
  • 18,936
  • 14
  • 70
  • 123
  • Apparently, CSS will do: https://stackoverflow.com/questions/41832199/is-it-possible-to-do-conditional-content-projection-transclusion-in-angular-2. I'm curious though if there are other ways. – Zlatko Mar 05 '18 at 15:13

1 Answers1

1

You can create a directive with selector card-body.

@Directive({selector: '[card-body]'})
export class CardBodyDirective {
}

Then in my-card component, use it as follows

@Component({
  selector: 'my-card',
  template: `
    <div class="card">
      <ng-content select="[card-body]"></ng-content>
      <div *ngIf="!cardBody">Default text</div>
    </div>
  `
})
export class MyCardComponent  {
  @ContentChild(CardBodyDirective) cardBody;

}

Do not forget to declare CardBodyDirective and export in the same module.

You can take a look at this stackblitz

Bunyamin Coskuner
  • 8,719
  • 1
  • 28
  • 48
  • I took a variation of this to make my thing work. I didn't put all of the problem in my question as it seemed irrelevant, but I actually want to pass nested selector further as another nested selector. – Zlatko Mar 06 '18 at 08:37
  • Can you elaborate little further? I might be help. I just didn't quite understand your last sentence. – Bunyamin Coskuner Mar 06 '18 at 08:41
  • Well, I tried to re-project content. Apparently, there is an ngProjectAs directive to help out with that. – Zlatko Mar 06 '18 at 14:51