Reusable components with Angular
One of the fundamental concepts that I learned about system design is to have/build reusable components. This approach saves time (building and testing the components) and writing boilerplate code.
I am learning Angular and I have found how to build re-usable components in Angular. In Angular, re-usable components are built using two approaches depending on the requirement, a good number of times these are combined.
- @Input() – decorator (Part of Component API)
- Ng-content directive (Content Projection)
In this article, I am going to show how to use the first approach to achieve component re-usability with @Input() – decorator.
@Input() – decorator - allows you to pass data from parent component to child component. You will not be able to pass HTML. I have taken Bootstrap Card component for this example, and I intend to use this component in multiple places on my site but with different/dynamic headings. Instead of having multiple Cards with different headings, I am going to have one Card. This card is designed in such a way that the consumer/user of the component/card can pass in the heading at the time of calling the component.
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-re-usable-card',
templateUrl: './re-usable-card.component.html',
styleUrls: ['./re-usable-card.component.css']
})
export class ReUsableCardComponent implements OnInit {
@Input() heading: string;
constructor() { }
ngOnInit() {
}
}
@Input() heading: string;
This line uses @Input() decorator to mark the property heading as one that can be passed on dynamically, making ReUsableCardComponent re-usable. Do not forget to import Input. Now the template for our re-usable component looks like below:
<div class="card">
<div class="card-header">
{{heading}}
</div>
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
{{heading}}
- binds the property heading of our component through string interpolation. Whatever that is passed from parent component targeting heading will be rendered inside this div
<div class="card-header">
//will be put here!
</div>
The below code shows how we pass data from the parent component to our child component.
<div class="container">
<div class="row">
<app-re-usable-card [heading]="'Heading 1'"></app-re-usable-card>
<app-re-usable-card heading='Heading 2'></app-re-usable-card>
</div>
</div>
Did you notice that in the card-body div
of our component there is HTML content? Is there a way of dynamically injecting/putting that content for re-usability? Yes, that is the job of ng-content, I will look into that in the next article. Thank you for reading, I appreciate comments!
Top comments (0)