Saurabh Kumar
Saurabh Kumar

Reputation: 61

How to pass html element as child in Angular Higher Order Components (HOC)?

I want to pass an HTML element in my Angular Higher Order Component. Right now I'm passing child element as a @Input decorator. My HOC, Main Container is like this.

<div>
 <p> MY EXTRA UI HERE</p>
 <ng-container *ngComponentOutlet="child"></ng-container>
</div>

@Component({
  selector: 'app-main-container',
  templateUrl: './main-container.component.html',
  styleUrls: ['./main-container.component.scss'],
})
export class MainContainerComponent {
  @Input() child
}

In other components I'm using my HOC like this

My Current code:

<app-main-container [child]="child"></app-main-container>

in .ts file I'm passing my child component like this

import { SidebarComponent } from '../sidebar/sidebar.component'
@Component({
  selector: 'app-staff',
  templateUrl: './staff.component.html',
  styleUrls: ['./staff.component.scss'],
})
export class StaffComponent {
  child: any = SidebarComponent
}

Now what I want to do is, something like this in React format

<app-main-container> 
    <app-staff-sidebar></app-staff-sidebar>
</app-main-container>

Upvotes: 1

Views: 2400

Answers (1)

Philipp Meissner
Philipp Meissner

Reputation: 5482

Given the structure you defined in your question

<app-main-container> 
    <app-staff-sidebar></app-staff-sidebar>
</app-main-container>

we can achieve this using ng-content.

Your main-container.component.html should accept it like so:

<div class="main-container">
  <ng-content></ng-content> <!-- This will be exchanged with the `<app-staff-sidebar></app-staff-sidebar>` that you passed in.
</div>

Assuming you want to insert more content that should be rendered a little differently than just by plain yielding, you can use slots represented by the select keyword. It is basically trying to find the provided pattern.

Calling the structure like so:

<app-main-container>
  <app-staff-sidebar data-slot-type="right"></app-staff-sidebar>
  <div data-slot-type="left"></div>
</app-main-container>

And accepting the slots like this:

<div class="main-container">
  <ng-content select="[data-slot-type=left]"></ng-content>
  <ng-content select="[data-slot-type=right]"></ng-content>
</div>

The select can match any given pattern. It can be a CSS class, an entire tag or anything else the DOM represents.

Upvotes: 2

Related Questions