Angular Template Inheritance and/or Composition

I'm an angular newbie coming from a server-side world. In fact, I am so "new" I am not even sure I can ask my question intelligently.

Anyway, here's my problem statement:

We are creating an app that consists of many cards (imagine a board with sticky notes). These cards will have some shared behaviors: same logic for the header, 'assign to' functionality, maximize/collapse ability etc. However, the content of these cards might be different: text, picture, ag-Grid, custom component etc.

The first thing that comes to my back-end-oriented mind is to create a parent Card class with a template like this:

<h2>Card header and shared elements</h2>
<cardContent></cardContent>

where cardContent is going to be replaced by actual content. Then extend this class for PictureCard, TextCard etc. and somehow pass/set cardContent.

How would you do this in Angular? Is this a wrong approach?

1 answer

  • answered 2018-10-09 16:26 danday74

    You want to use content projection which was previously known as transclusion.

    With content projection, you basically have some common elements but can pass in some additional content too, whatever content you like.

    It works something like this (we will call this component fred):

    <h2>{{title}}</h2> 
    <ng-content></ng-content>
    

    Title would be passed as an @Input. The component that uses fred would look like this:

    <fred [title]="i will appear as title">
      <div>I will be displayed where ng-content is</div>
      <p>i can be anything you want</p>
    </fred>
    
    <fred [title]="i will appear as a different title">
      <a-different-component></a-different-component>
    </fred>
    

    Here we are using fred twice, passing in totally different content.

    Here's a tutorial:

    https://codecraft.tv/courses/angular/components/content-projection/

    This is a common approach for custom modals where a lot of the structure is the same - e.g. modal title, modal footer, etc but where the content of the modal body differs every time.

    Sorry can't find the official docs on this but that link is good.

    The great thing about Angular content projection is that you can have multiple content slots which means you can project into multiple places if need be. Which makes Angular content projection the most powerful content projection system available. #ReactCantBeatThis

    Having said all this, you may want to use some out the box library solution such as primeng card:

    https://www.primefaces.org/primeng/#/card

    There are lots of libs out there to choose from! primeng is one of the leaders.