🎭 Angular Content Projection: The Magic Mail Slot
The Story of the Magical Mailbox
Imagine you have a special magic mailbox 📬 at your house. This isn’t just any mailbox—it has special slots where people can drop different things:
- A big slot for packages 📦
- A medium slot for letters ✉️
- A tiny slot for coins 🪙
Your mailbox doesn’t care WHAT goes inside. It just provides the slots and lets people put their stuff through!
That’s exactly what Content Projection does in Angular!
🎯 What is Content Projection?
Content Projection is when a parent component puts content inside a child component.
Think of it like this:
- The child component is the mailbox 📬
- The parent component is the person dropping mail ✉️
- The slot is
<ng-content>
The Simple Idea
<!-- Parent says: "Here's my stuff!" -->
<my-card>
<h1>Hello World!</h1>
<p>This goes INSIDE the card</p>
</my-card>
<!-- Child (my-card) says: "I'll put it here!" -->
<div class="card-box">
<ng-content></ng-content>
</div>
Result? The <h1> and <p> appear INSIDE the card-box! 🎉
📮 Understanding <ng-content>
<ng-content> is Angular’s magic slot.
It says: “Whatever the parent puts between my tags, show it RIGHT HERE.”
A Real Example: The Card Component
// card.component.ts
@Component({
selector: 'app-card',
template: `
<div class="pretty-card">
<ng-content></ng-content>
</div>
`
})
export class CardComponent {}
<!-- Using the card -->
<app-card>
<img src="cat.jpg" alt="cute cat">
<h3>My Cat Photos</h3>
</app-card>
The image and heading project into the card! ✨
🎰 Multi-Slot Projection: Many Doors, Many Rooms!
Sometimes one slot isn’t enough. Imagine a treasure chest with:
- A slot for gold coins 🪙
- A slot for gems 💎
- A slot for scrolls 📜
Multi-slot projection lets you have multiple <ng-content> tags that catch different content!
The Magic: select Attribute
<!-- Child component template -->
<div class="header">
<ng-content select="[header]"></ng-content>
</div>
<div class="body">
<ng-content select="[body]"></ng-content>
</div>
<div class="footer">
<ng-content></ng-content>
</div>
<!-- Parent using it -->
<app-layout>
<h1 header>Welcome!</h1>
<p body>Main content here</p>
<span>Footer stuff</span>
</app-layout>
How select Works
| Selector | What It Catches |
|---|---|
select="[header]" |
Elements with header attribute |
select=".title" |
Elements with title class |
select="h1" |
All <h1> elements |
| (no select) | Everything not caught elsewhere |
🎨 Selector Types for Multi-Slot
graph TD A["Parent Content"] --> B{Which Slot?} B -->|Attribute| C["[header]"] B -->|Class| D[".title"] B -->|Element| E["h1, p, span"] B -->|Default| F["No selector"]
Example: Dialog with Three Slots
@Component({
selector: 'app-dialog',
template: `
<div class="dialog">
<header>
<ng-content select="[dialog-title]">
</ng-content>
</header>
<main>
<ng-content select="[dialog-body]">
</ng-content>
</main>
<footer>
<ng-content select="[dialog-actions]">
</ng-content>
</footer>
</div>
`
})
export class DialogComponent {}
<!-- Using the dialog -->
<app-dialog>
<h2 dialog-title>Confirm Delete</h2>
<p dialog-body>Are you sure?</p>
<button dialog-actions>Yes</button>
<button dialog-actions>No</button>
</app-dialog>
Both buttons go to the dialog-actions slot! 🎯
🧠 Why Use Content Projection?
✅ Flexibility
Create reusable containers that work with ANY content.
✅ Clean Code
Keep your components simple and focused.
✅ Customization
Let users of your component decide what goes inside.
🌟 Quick Comparison
| Feature | What It Does |
|---|---|
<ng-content> |
Single slot—catches all |
<ng-content select="..."> |
Targeted slot—catches specific |
| Default slot | Catches leftovers |
🚀 Key Takeaways
- Content Projection = Parent puts content inside child
<ng-content>= The magic slot that displays projected content- Multi-slot = Use
selectto catch specific content - Default slot =
<ng-content>with noselectcatches remaining content
🎭 Remember the Mailbox!
graph TD A["📬 Child Component"] --> B["Slot 1: header"] A --> C["Slot 2: body"] A --> D["Slot 3: default"] E["Parent Content"] --> B E --> C E --> D
Your component is the mailbox. <ng-content> is the slot. The parent drops in whatever they want!
You’re now a Content Projection Pro! 🎉
