#10 Angular Components and Templates

#10 Angular Components and Templates

Angular components and templates are the cornerstone of building robust and interactive user interfaces. This article delves into the intricacies of Angular components, their interactions, lifecycle hooks, and how to effectively use templates. Additionally, we will explore working with forms, creating custom directives and pipes, and handling dynamic components.

6.1 Understanding Angular Components

Angular components are the fundamental building blocks of an Angular application. Each component consists of a TypeScript class, an HTML template, and optional CSS styles.

Key Elements of an Angular Component
  • TypeScript Class: Defines the component’s behavior and properties.
  • HTML Template: Defines the component’s view.
  • CSS Styles: Optional styles scoped to the component.
Example
import { Component } from '@angular/core';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.css']
})
export class MyComponent {
  title = 'Hello, Angular!';
}
<!-- my-component.component.html -->
<h1>{{ title }}</h1>

6.2 Component Interaction

Components in Angular can interact with each other in various ways, including parent-child and sibling communication.

Parent to Child

Use @Input() decorator to pass data from a parent component to a child component.

// parent.component.html
<app-child [childProperty]="parentProperty"></app-child>

// child.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html'
})
export class ChildComponent {
  @Input() childProperty: string;
}

Child to Parent

Use @Output() decorator and EventEmitter to emit events from a child component to a parent component.

// child.component.ts
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html'
})
export class ChildComponent {
  @Output() notify: EventEmitter<string> = new EventEmitter<string>();

  sendNotification() {
    this.notify.emit('Message from child');
  }
}

// parent.component.html
<app-child (notify)="handleNotification($event)"></app-child>

// parent.component.ts
handleNotification(message: string) {
  console.log(message);
}

6.3 Lifecycle Hooks

Angular provides lifecycle hooks to tap into key moments in a component’s lifecycle.

Common Lifecycle Hooks
  • ngOnInit(): Called once, after the first ngOnChanges.
  • ngOnChanges(): Called before ngOnInit() and whenever one or more data-bound input properties change.
  • ngOnDestroy(): Called once, just before the instance is destroyed.
Example
import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-lifecycle-demo',
  templateUrl: './lifecycle-demo.component.html'
})
export class LifecycleDemoComponent implements OnInit, OnDestroy {
  ngOnInit() {
    console.log('Component initialized');
  }

  ngOnDestroy() {
    console.log('Component destroyed');
  }
}

6.4 Template Syntax and Expressions

Angular’s template syntax allows for binding data from the component to the view and vice versa.

Interpolation
<p>{{ title }}</p>

Property Binding

<img [src]="imageUrl">

Event Binding

<button (click)="handleClick()">Click me</button>

Two-Way Binding

<input [(ngModel)]="name">

6.5 Working with Forms (Template-driven and Reactive Forms)

Angular provides two approaches to handle forms: template-driven and reactive forms.

Template-Driven Forms

Suitable for simple forms. Use Angular directives to bind data.

<!-- template-driven-form.component.html -->
<form #form="ngForm" (ngSubmit)="onSubmit(form)">
  <input name="name" ngModel required>
  <button type="submit">Submit</button>
</form>

Reactive Forms

Suitable for complex forms. Use FormGroup and FormControl.

// reactive-form.component.ts
import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-reactive-form',
  templateUrl: './reactive-form.component.html'
})
export class ReactiveFormComponent {
  form = new FormGroup({
    name: new FormControl('')
  });

  onSubmit() {
    console.log(this.form.value);
  }
}
<!-- reactive-form.component.html -->
<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <input formControlName="name">
  <button type="submit">Submit</button>
</form>

6.6 Custom Directives and Pipes

Directives and pipes allow you to extend HTML’s capabilities and transform data.

Custom Directives

Create a custom directive to modify the behavior of elements.

// highlight.directive.ts
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor(private el: ElementRef, private renderer: Renderer2) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.renderer.setStyle(this.el.nativeElement, 'color', 'blue');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.renderer.removeStyle(this.el.nativeElement, 'color');
  }
}

Custom Pipes

Create a custom pipe to transform data.

// exclamation.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'exclamation' })
export class ExclamationPipe implements PipeTransform {
  transform(value: string): string {
    return value + '!';
  }
}
<p>{{ 'Hello' | exclamation }}</p>

6.7 Dynamic Components

Dynamic components are created and rendered at runtime.

Steps to Create Dynamic Components
  1. Create a Component Factory:
// dynamic.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-dynamic',
  template: '<p>Dynamic Component</p>'
})
export class DynamicComponent {}

2. Use ComponentFactoryResolver:

// dynamic-host.component.ts
import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { DynamicComponent } from './dynamic.component';

@Component({
  selector: 'app-dynamic-host',
  template: '<ng-template #dynamicContainer></ng-template>'
})
export class DynamicHostComponent {
  @ViewChild('dynamicContainer', { read: ViewContainerRef, static: true }) container: ViewContainerRef;

  constructor(private resolver: ComponentFactoryResolver) {}

  ngOnInit() {
    const factory = this.resolver.resolveComponentFactory(DynamicComponent);
    this.container.createComponent(factory);
  }
}

Conclusion

By mastering these aspects of Angular components and templates, you’ll be well-equipped to create dynamic, responsive, and maintainable applications. Angular’s powerful tools and features streamline the development process, allowing you to focus on building great user experiences.

#Angular #WebDevelopment #AngularComponents #FrontendDevelopment #TypeScript #JavaScript #AngularTemplates #ComponentInteraction #LifecycleHooks #AngularForms #ReactiveForms #TemplateDrivenForms #CustomDirectives #CustomPipes #DynamicComponents #AngularTutorial #WebDev #Coding #Programming #LearnAngular #AngularDirectives #AngularPipes

Leave a Reply