This Article helps to understand the concept of Content Projection in Angular using ContentChildren (ng-content)- Access Html Element
Content Projection in Angular may be performed with ContentChild and ContentChildren.
ContentChild and ContentChildren are property decorators. They are used to query or helps to get a reference to the projected content. Content received by the child component from its parent component is referred to as projected content. Conversely, a parent component utilises ViewChild or ContentChild to gain access to a child component.
ContentChildren - Access Html Element
If we have more than one ContentChild, we can access them as ContentChildren
Parent Container - Level 1
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-cards',
templateUrl: './cards.component.html',
styleUrls: ['./cards.component.sass']
})
export class CardsComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
<app-cardcontainer>
<app-carddetail label="Tab 1">
<p>Card 1 goes here.p>
app-carddetail>
<app-carddetail label="Tab 2" [active]="true">
<p>Card 2 goes here.p>
app-carddetail>
<app-carddetail label="Tab 3">
<p>Card 3 goes here.p>
app-carddetail>
app-cardcontainer>
Child Container - Content binding
import {
Component,
OnInit,
ContentChildren,
QueryList,
AfterContentInit,
} from "@angular/core";
import { CarddetailComponent } from "../carddetail/carddetail.component";
@Component({
selector: "app-cardcontainer",
templateUrl: "./cardcontainer.component.html",
styleUrls: ["./cardcontainer.component.sass"],
})
export class CardcontainerComponent implements OnInit, AfterContentInit {
@ContentChildren(CarddetailComponent) tabs: QueryList<CarddetailComponent>;
constructor() {}
ngOnInit() {}
ngAfterContentInit() {
// Initialize the first tab as active.
if (this.tabs.length > 0) {
this.tabs.forEach((tab) => (tab.active = true));
}
}
}
<div class="tab-group">
<div class="tab-labels">
<ng-container *ngFor="let tab of tabs">
<div>Card Containerdiv>
ng-container>
div>
<ng-content>ng-content>
Grand Child
import {
AfterContentInit,
Component,
ContentChild,
ElementRef,
Input,
} from "@angular/core";
@Component({
selector: "app-carddetail",
templateUrl: "./carddetail.component.html",
styleUrls: ["./carddetail.component.sass"],
})
export class CarddetailComponent {
@Input() label: string;
@Input() active = false;
}
<div [hidden]="!active">
<ng-content>ng-content>
div>