Angular Components: Building Blocks of Your Angular Application

Angular Components: Building Blocks of Your Angular Application

·

5 min read

Angular components are the fundamental building blocks of Angular applications. Each component controls a part of the user interface (UI) and is responsible for displaying data, handling user interaction, and providing functionality.

Understanding Angular components is crucial for any Angular developer, from beginners to advanced. Let’s break down Angular components from the fundamentals to more advanced concepts, with simple examples for each.

What is an Angular Component?

An Angular component is a class that defines a view, and its associated logic, and controls how a section of the UI behaves. Each component in Angular has:

  • A Template (HTML view) that defines the structure of the UI.

  • A Class (TypeScript code) that defines the logic and behavior of the view.

  • Styles (CSS or SCSS) to define the appearance of the component.

1. Component Structure

At the core, a component consists of:

  1. Component Class (written in TypeScript)

  2. Template (HTML)

  3. Styles (CSS/SCSS)

  4. Metadata (decorated with @Component decorator)

Example of a Basic Angular Component

Let’s go step-by-step to create a simple Angular component:

Step 1: Create a Component

You can generate a component using Angular CLI:

bashCopy codeng generate component user

This generates:

  • user.component.ts (component class)

  • user.component.html (template)

  • user.component.css (styles)

  • user.component.spec.ts (for testing)

Step 2: Basic Component Class (user.component.ts)

typescriptCopy codeimport { Component } from '@angular/core';

@Component({
  selector: 'app-user',            // The tag to represent the component in HTML
  templateUrl: './user.component.html',  // The HTML template for the component
  styleUrls: ['./user.component.css']    // The styles for the component
})
export class UserComponent {
  username = 'John Doe'; // Property to bind to template

  constructor() { }

  changeUsername(newName: string) {
    this.username = newName;  // Method to update the username
  }
}

Step 3: Component Template (user.component.html)

htmlCopy code<div class="user-container">
  <h2>Welcome, {{ username }}!</h2> <!-- Interpolation binding -->
  <button (click)="changeUsername('Jane Smith')">Change Username</button> <!-- Event binding -->
</div>

Step 4: Component Styles (user.component.css)

cssCopy code.user-container {
  background-color: #f0f0f0;
  padding: 20px;
  border-radius: 5px;
  text-align: center;
}
button {
  padding: 10px 20px;
  font-size: 16px;
}

Key Concepts in Angular Components

  1. Component Decorator (@Component)

    • The @Component decorator tells Angular that the class is a component and provides metadata for Angular to understand how it should be processed.

    • The metadata includes:

      • selector: The custom HTML tag used to represent the component.

      • templateUrl: The path to the component’s HTML template.

      • styleUrls: The path to the component’s styles.

  2. Component Class

    • The class defines properties (data) and methods (logic) to manage the view. It can also interact with services, handle user input, and perform other tasks.
  3. Template

    • The template defines the structure of the UI and how it connects to the component class. It uses Angular directives like *ngIf, *ngFor, etc., and Angular binding techniques like interpolation, property binding, event binding, and two-way binding.
  4. Styles

    • Styles control the look and feel of the component. You can use global styles or component-specific styles, which are scoped to that component.

Advanced Concepts in Angular Components

After understanding the basics of components, let’s dive into more advanced topics.

1. Lifecycle Hooks

Angular components have lifecycle hooks that allow you to tap into different stages of the component’s lifecycle.

Some of the most commonly used lifecycle hooks:

  • ngOnInit(): Called once after the component is initialized (good for data fetching or setup).

  • ngOnChanges(): Called whenever an input property of the component changes.

  • ngOnDestroy(): Called just before the component is destroyed (good for cleanup tasks).

  • ngAfterViewInit(): Called after the component’s view has been fully initialized.

Example: Using ngOnInit():

typescriptCopy codeimport { Component, OnInit } from '@angular/core';

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

  ngOnInit() {
    this.username = 'Initializing...';
    setTimeout(() => {
      this.username = 'John Doe'; // Simulate a data fetch
    }, 2000);
  }
}

2. Input and Output Properties (Data Binding between Components)

In Angular, components can communicate with each other using @Input and @Output.

  • @Input(): Allows a parent component to pass data to a child component.

  • @Output(): Allows a child component to emit an event that the parent component can listen to.

Example: Parent-Child Communication:

Parent Component (AppComponent) (app.component.ts)
typescriptCopy codeimport { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<app-user [username]="parentUsername" (usernameChanged)="updateUsername($event)"></app-user>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  parentUsername = 'Parent User';

  updateUsername(newName: string) {
    this.parentUsername = newName;
  }
}
Child Component (UserComponent) (user.component.ts)
typescriptCopy codeimport { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css']
})
export class UserComponent {
  @Input() username: string; // Input property
  @Output() usernameChanged = new EventEmitter<string>(); // Output property

  changeUsername() {
    this.usernameChanged.emit('New Username');
  }
}
Child Template (user.component.html)
htmlCopy code<div>
  <h2>{{ username }}</h2>
  <button (click)="changeUsername()">Change Username</button>
</div>

3. Dynamic Components

Sometimes, you may need to load components dynamically. This can be achieved using ComponentFactoryResolver and ViewContainerRef.

Example of Dynamic Component Loading:

typescriptCopy codeimport { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';

@Component({
  selector: 'app-root',
  template: `<button (click)="loadComponent()">Load Dynamic Component</button>
            <ng-container #dynamicComponentContainer></ng-container>`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild('dynamicComponentContainer', { read: ViewContainerRef }) container: ViewContainerRef;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}

  loadComponent() {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(DynamicComponent);
    this.container.clear(); // Clear previous components
    this.container.createComponent(componentFactory);
  }
}

4. Component Inheritance

You can extend a component class to reuse functionality across multiple components.

Example of Component Inheritance:

typescriptCopy codeimport { Component } from '@angular/core';

class BaseComponent {
  title = 'Base Component';
}

@Component({
  selector: 'app-child',
  template: `<h1>{{ title }}</h1>`
})
export class ChildComponent extends BaseComponent {
  constructor() {
    super();
    this.title = 'Child Component'; // Overridden title
  }
}

Conclusion

  1. Components are the heart of Angular applications, representing both the UI and the logic.

  2. They consist of HTML templates, TypeScript logic, and CSS styles.

  3. You can use lifecycle hooks to tap into the component's lifecycle and @Input and @Output to communicate between parent and child components.

  4. More advanced topics include dynamic components and component inheritance.