Cards are a fundamental user interface element used to structure and display content. In Angular, we can create versatile and customizable card components using the ng-content
directive. ng-content
enables us to project content from the parent component into the child component, making it highly adaptable for various use cases. One of the powerful features of ng-content
is the select
attribute, which allows us to selectively project specific content into the child component.
In this tutorial, we’ll guide you through the process of creating a customizable card component using ng-content
, with a focus on how to use the select
attribute to precisely control which content gets projected into the child component.
Prerequisites
Before we dive in, ensure you have the following prerequisites in place:
- Basic knowledge of Angular.
- Angular CLI installed on your system.
- A code editor of your choice (e.g., Visual Studio Code).
Getting Started
Let’s begin by creating a new Angular project and generating the card component.
ng new customizable-card-demo
cd customizable-card-demo
ng generate component card
This will set up a new Angular project and generate a card
component for us.
Building the Customizable Card Component
- Open the
card.component.html
file and define the basic structure of the card. We’ll keep it simple with a card title, content, and buttons.
<div class="card">
<div class="card-title">
<ng-content select="[card-title]"></ng-content>
</div>
<div class="card-content">
<ng-content></ng-content>
</div>
<div class="card-actions">
<ng-content select="[card-actions]"></ng-content>
</div>
</div>
In the code above, notice the use of the select
attribute within ng-content
. We’re using [card-title]
, :host
, and [card-actions]
as selectors to target specific elements or attributes for content projection. This means that content enclosed in elements with these attributes or elements themselves will be projected into the respective <ng-content>
tags within the card component.
- Style your card by adding CSS rules to the
card.component.css
file. You can customize the styles according to your project’s design.
.card {
border: 1px solid #ccc;
border-radius: 4px;
padding: 16px;
margin: 16px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.card-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 12px;
}
.card-content {
font-size: 16px;
}
.card-actions {
margin-top: 16px;
display: flex;
justify-content: space-between;
}
- In the
app.component.html
file, create a sample card with a custom title, content, and buttons:
<app-card>
<div card-title>Custom Card Title</div>
<p>This is the content of the custom card component. You can place any content here.</p>
<div card-actions>
<button (click)="onButton1Click()">Button 1</button>
<button (click)="onButton2Click()">Button 2</button>
</div>
</app-card>
- In the
app.component.ts
file, add the corresponding event handlers:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-card>
<div card-title>Custom Card Title</div>
<p>This is the content of the custom card component. You can place any content here.</p>
<div card-actions>
<button (click)="onButton1Click()">Button 1</button>
<button (click)="onButton2Click()">Button 2</button>
</div>
</app-card>
`
})
export class AppComponent {
onButton1Click() {
alert('Button 1 Clicked');
}
onButton2Click() {
alert('Button 2 Clicked');
}
}
- Serve your Angular application and open it in a web browser:
ng serve --open
You should now see your customizable card displayed in the browser with the specified title, content, and buttons. Clicking the buttons will trigger the corresponding events.
Understanding the select
Attribute
The select
attribute in ng-content
is a powerful tool for precise content projection. It allows you to target specific elements or attributes within the parent component’s template. When you use the select
attribute, Angular looks for elements in the parent component that match the provided selector and projects only those elements into the corresponding <ng-content>
tag in the child component.
In our example, we used [card-title]
, :host
, and [card-actions]
as selectors. Here’s what each of them does:
-
[card-title]
: This selector looks for elements with thecard-title
attribute in the parent component’s template. Any content enclosed within such elements is projected into the<ng-content select="[card-title]">
tag in the child component. This allows you to customize the card’s title. -
:host
: This special selector refers to the host element itself, which is the<app-card>
element in our case. Using:host
, we can project content that is not enclosed within any specific element in the parent component’s template. This is useful for projecting general content into the card. -
[card-actions]
: Similar to[card-title]
, this selector targets elements with thecard-actions
attribute in the parent component’s template. Content within these elements is projected into the<ng-content select="[card-actions]">
tag in the child component, allowing you to customize card actions.
By using the select
attribute, you gain fine-grained control over which parts of the parent component’s content should be included in the child component, making your card component highly customizable and versatile.
Conclusion
In this tutorial, we’ve explored how to create a customizable card component in Angular using ng-content
. We’ve also delved into the power of the select
attribute, which enables us to selectively project specific content into the child component based on elements or attributes. This approach provides a flexible and reusable solution for creating cards with tailored content and functionality. You can further enhance your card component by adding more features, such as images or additional styling options.