Angular Components: A Comprehensive Guide with Simple Examples on 2024

Angular Components: A Comprehensive Guide with Simple Examples on 2024

Angular Components serve as the fundamental elements within the Angular framework, enabling developers to craft dynamic and adaptable web applications. At the heart of Angular lie these Components, acting as the cornerstone of any Angular project. Throughout this guide, we delve deeply into the realm of Angular Components, elucidating their attributes, variations, and methods of interaction between disparate components. Through lucid examples, we aim to empower you to grasp the intricacies of Angular Components, leveraging their versatility to its utmost in your endeavors.

Understanding Angular Components

Any Angular application’s foundation is made up of Angular components. They are reusable components that provide functionality and style related to a section of the user interface. Building scalable and successful apps requires an understanding of how to design, manage, and use Angular components. We’ll get more into the lifetime of Angular components, their anatomy, and recommended practices for Angular Components based architecture in this part.

Anatomy of an Angular Component

Several essential components make to an angular component:

  • Component Class: The TypeScript class defining the behavior of the component.
  • Decorator: The @Component decorator, which offers the component’s selector, template, and styles, among other metadata.
  • Template: The HTML that specifies the component’s view.
  • Styles: CSS that specifies how a component looks.
  • Metadata: Data that links a class to its template and styling and is supplied by the @Component decorator.

Creating an Angular Component

To create an Angular component, you can use the Angular CLI command:

ng generate component example

This command generates the following files:

  • example.component.ts: The TypeScript file containing the component class.
  • example.component.html: The HTML template file.
  • example.component.css: The CSS file for styles.
  • example.component.spec.ts: The test file for the component.

Example: Basic Angular Component

Let’s start with a simple example of an Angular component.

Step 1: Creating the Component

First, generate the component using the Angular CLI:

ng generate component greeting

This command will create a folder named greeting with the necessary files.

Step 2: Defining the Component Class

Open the greeting.component.ts file and define the component class:

import { Component } from '@angular/core';

@Component({
  selector: 'app-greeting',
  templateUrl: './greeting.component.html',
  styleUrls: ['./greeting.component.css']
})
export class GreetingComponent {
  message: string = 'Hello, Angular!';

  updateMessage() {
    this.message = 'Welcome to the Angular world!';
  }
}

In this example, we define a property message and a method updateMessage to change the message.

Step 3: Creating the Template

Open the greeting.component.html file and add the following HTML:

<div>
  <h1>{{ message }}</h1>
  <button (click)="updateMessage()">Click Me</button>
</div>

This template displays the message property and includes a button to trigger the updateMessage method.

Step 4: Adding Styles

Open the greeting.component.css file and add some basic styles:

div {
  text-align: center;
  margin-top: 50px;
}

button {
  padding: 10px 20px;
  font-size: 16px;
}

Result

When you run your Angular application, you should see the message “Hello, Angular!” and a button. Clicking the button changes the message to “Welcome to the Angular world!”.

Lifecycle of an Angular Component

From construction to destruction, there are several stages in the lifespan of an angular component. Angular has lifecycle hooks so you may access these phases. The lifecycle hooks that are most often utilized are:

  • One call to ngOnInit() follows the initial ngOnChanges(). Initializing data there is a smart idea.
  • ngOnChanges(): Whenever one or more data-bound input properties change, this lifecycle hook is called before any other.
  • ngDoCheck(): Sounded immediately following ngOnChanges() and ngOnInit() in each change detection run.
  • ngAfterContentInit(): Issued one time following the initial ngDoCheck() call.
  • ngAfterContentChecked(): This function is called following each ngDoCheck() and ngAfterContentInit().
  • One call to ngAfterViewInit() follows the initial ngAfterContentChecked().
  • ngAfterViewChecked(): This function is called following each consecutive ngAfterContentChecked() and ngAfterViewInit().
  • ngOnDestroy(): This function is called just before the component is destroyed by Angular.

Example: Lifecycle Hooks

import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';

@Component({
selector: 'app-lifecycle-demo',
template: '<p>Lifecycle Demo</p>',
styleUrls: ['./lifecycle-demo.component.css']
})
export class LifecycleDemoComponent implements OnInit, AfterViewInit, OnDestroy {

constructor() {
console.log('Constructor called');
}

ngOnInit(): void {
console.log('ngOnInit called');
}

ngAfterViewInit(): void {
console.log('ngAfterViewInit called');
}

ngOnDestroy(): void {
console.log('ngOnDestroy called');
}
}

Deep Dive into Angular Component Properties

Angular components come with a set of properties that enhance their functionality. These properties include inputs, outputs, lifecycle hooks, and more.

Inputs and Outputs

Inputs and outputs are used for communication between components. Inputs allow parent components to pass data to child components, while outputs allow child components to emit events to parent components.

Example: Using Inputs and Outputs

Let’s create a new component to demonstrate inputs and outputs.

ng generate component child

Child Component (child.component.ts)

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  @Input() childMessage: string;
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    this.messageEvent.emit('Hello from Child Component!');
  }
}

The @Input decorator allows the parent component to pass data to the childMessage property. The @Output decorator, along with the EventEmitter, allows the child component to send data to the parent component.

Child Component Template (child.component.html)

<div>
  <p>{{ childMessage }}</p>
  <button (click)="sendMessage()">Send Message</button>
</div>

Parent Component (app.component.ts)

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  parentMessage = 'Message from Parent Component';
  childMessage = '';

  receiveMessage($event: string) {
    this.childMessage = $event;
  }
}

Parent Component Template (app.component.html)

<div>
  <app-child [childMessage]="parentMessage" (messageEvent)="receiveMessage($event)"></app-child>
  <p>{{ childMessage }}</p>
</div>

Lifecycle Hooks

Lifecycle hooks allow you to tap into key events during the lifecycle of a component, such as when it is created, rendered, and destroyed.

Example: Using Lifecycle Hooks

import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-lifecycle',
  templateUrl: './lifecycle.component.html',
  styleUrls: ['./lifecycle.component.css']
})
export class LifecycleComponent implements OnInit, OnDestroy {
  constructor() {
    console.log('Constructor called');
  }

  ngOnInit(): void {
    console.log('ngOnInit called');
  }

  ngOnDestroy(): void {
    console.log('ngOnDestroy called');
  }
}

When you navigate to this component, you will see logs in the console indicating the different lifecycle stages.

Types of Angular Components and Their Files

Angular components can be categorized into different types based on their roles and responsibilities within the application.

Container Components

Container components are responsible for managing data and business logic. They often contain other components and provide data to them.

Example: Container Component

import { Component } from '@angular/core';

@Component({
  selector: 'app-container',
  templateUrl: './container.component.html',
  styleUrls: ['./container.component.css']
})
export class ContainerComponent {
  items = ['Item 1', 'Item 2', 'Item 3'];
}

Template (container.component.html)

<div>
  <ul>
    <li *ngFor="let item of items">{{ item }}</li>
  </ul>
</div>

Presentational Components

Presentational components focus on how things look. They receive data via inputs and emit events via outputs but contain little to no business logic.

Example: Presentational Component

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-presentational',
  templateUrl: './presentational.component.html',
  styleUrls: ['./presentational.component.css']
})
export class PresentationalComponent {
  @Input() data: string;
}

Template (presentational.component.html)

<div>
  <p>{{ data }}</p>
</div>

Routing Components

Angular routing components control how various views are shown inside a single-page application and how navigation is handled. The capacity to create dynamic, interactive web apps that offer a flawless user experience is essential. The fundamentals of Angular routing, such as creating routes, identifying routing components, and controlling navigation between them, will be covered in this part.

Setting Up Angular Routing

To get started with Angular routing, you need to configure the router in your application. The router is responsible for interpreting URL paths and loading the corresponding components.

Step 1: Install Angular Router

If you haven’t already, ensure that Angular Router is installed. This is typically included with a new Angular project, but you can add it using:

ng add @angular/router

Step 2: Configure Routes in the App Module

Define your application’s routes in the app-routing.module.ts file. Each route associates a path with a component.

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';

const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: '**', redirectTo: '', pathMatch: 'full' } // Redirect unknown routes to Home
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

Step 3: Create the Routing Components

Next, generate the components that correspond to each route using the Angular CLI:

ng generate component home
ng generate component about
ng generate component contact

Adding Navigation Links

To enable navigation between these routes, you need to add links to your application template. Use the routerLink directive to define the paths.

app.component.html

<nav>
<ul>
<li><a routerLink="">Home</a></li>
<li><a routerLink="about">About</a></li>
<li><a routerLink="contact">Contact</a></li>
</ul>
</nav>
<router-outlet></router-outlet>

Example: Routing Component

First, set up routing in your app-routing.module.ts:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Home Component (home.component.ts)

import { Component } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent { }

About Component (about.component.ts)

import { Component } from '@angular/core';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.css']
})
export class AboutComponent { }

Navigation Links (app.component.html)

<nav>
  <a routerLink="">Home</a>
  <a routerLink="about">About</a>
</nav>
<router-outlet></router-outlet>

Interacting Between Components

Components often need to share data and communicate with each other. This can be achieved using various methods.

ViewChild and ContentChild

ViewChild and ContentChild allow one component to access the properties and methods of another component.

Example: Using ViewChild

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child/child.component';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements AfterViewInit {
  @ViewChild(ChildComponent) child: ChildComponent;

  ngAfterViewInit() {
    console.log(this.child.childMessage);
    this.child.childMessage = 'Updated by Parent Component!';
  }
}

Service for Communication

Using a shared service is a common method for communication between components.

Step 1: Create the Service

ng generate

 service data

Data Service (data.service.ts)

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private messageSource = new BehaviorSubject<string>('Default Message');
  currentMessage = this.messageSource.asObservable();

  changeMessage(message: string) {
    this.messageSource.next(message);
  }
}

Step 2: Using the Service in Components

Parent Component (parent.component.ts)

import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
  message: string;

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.dataService.currentMessage.subscribe(message => this.message = message);
  }

  newMessage() {
    this.dataService.changeMessage('Hello from Parent Component!');
  }
}

Parent Template (parent.component.html)

<div>
  <p>Parent Message: {{ message }}</p>
  <button (click)="newMessage()">New Message</button>
</div>
<app-child></app-child>

Child Component (child.component.ts)

import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  message: string;

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.dataService.currentMessage.subscribe(message => this.message = message);
  }
}

Child Template (child.component.html)

<div>
  <p>Child Message: {{ message }}</p>
</div>

Conclusion

Angular Components serve as the cornerstone for constructing robust and sustainable applications. Understanding how to develop and utilize components, oversee their attributes, and facilitate communication between them empowers developers to harness the complete potential of Angular. Whether you’re handling straightforward UI elements or navigating intricate interactions, proficiency in Angular Components will substantially elevate your development prowess.

Other : Mastering Angular: A Comprehensive Introduction For Beginners On 2024

Leave a Reply

Your email address will not be published. Required fields are marked *