Angular Core Decorators and Concepts with Examples


Angular Core Decorators and Concepts

Angular’s architecture revolves around decorators, modules, components, directives, pipes, dependency injection, data binding, and lifecycle hooks. Together, these form the “methods” or building blocks you’ll use in every Angular application. Below is a comprehensive list—if you spot something missing, it’s likely tucked away in the advanced decorators section further down.

1. Core Decorators

These decorators tell Angular how to process a class or property at runtime.

  • @NgModule Defines an Angular module, grouping components, directives, pipes, and services. Sets up the compilation context and dependency injector scope.

  • @Component A specialized @Directive with a template. Marks a class as an Angular component and provides metadata like selector, templateUrl, styles, change detection strategy, and providers.

  • @Directive Creates attribute or structural directives. You can modify the DOM or component behavior without a template.

  • @Pipe Transforms input values to output values in templates. You can define pure or impure pipes to optimize change detection.

  • @Injectable Marks a class as available for injection and can specify providedIn scope (root, a module, or a component).

2. Data Binding

Angular offers multiple binding syntaxes in templates for communication between component class and DOM.

  • Interpolation ({{ value }}) Embed component properties directly into text content.

  • Property Binding ([property]="value") Bind component data to element or directive inputs.

  • Attribute/Class/Style Binding

    • [attr.aria-label]="label"

    • [class.active]="isActive"

    • [style.width.px]="width"

  • Event Binding ((event)="handler($event)") Listen to DOM events and call component methods.

  • Two-Way Binding ([(ngModel)]="property") Combines property and event binding in one. Requires importing FormsModule or ReactiveFormsModule.

3. Components & Templates

Components are the primary UI building blocks. Their templates support:

  • Structural directives (*ngIf, *ngFor, *ngSwitchCase)

  • Template reference variables (#ref)

  • Content projection (<ng-content>)

Components also expose inputs and outputs:

  • @Input() Exposes a property to the parent component for data flow down.

  • @Output() Emits events to the parent component via EventEmitter.

  • EventEmitter<T> A generic class for emitting custom events. You call .emit(value) in the child and listen with (output)="handler($event)" in the parent.

4. Dependency Injection

Angular’s DI system is hierarchical and powerful:

  • Providers can be registered at module, component, or directive level.

  • You configure them using:

    • providedIn in @Injectable()

    • providers array in @NgModule or @Component

  • Built-in injection tokens: PLATFORM_ID, DOCUMENT, Injector

  • Constructor injection: Angular resolves and supplies dependencies when instantiating classes.

5. Directives

Beyond @Component and @Directive decorators, you get two major categories:

  1. Structural Directives Change DOM layout by adding, removing, or manipulating elements.

    • *ngIf

    • *ngFor

    • *ngSwitch

  2. Attribute Directives Change the appearance or behavior of an element.

    • Built-in: [ngClass], [ngStyle], ngModel

    • Custom: Use @Directive({ selector: '[yourDirective]' }) and inject ElementRef or Renderer2.

6. Advanced Decorators & Query APIs

Angular provides several decorators to tap into host elements, children, and lifecycle:

  • @HostBinding() Bind a property to a host element’s property or attribute.

  • @HostListener() Subscribe to DOM events on the host element.

  • @ViewChild() / @ViewChildren() Query for a child component, directive, or DOM element in the component’s view.

  • @ContentChild() / @ContentChildren() Query projected content from a parent component’s <ng-content>.

7. Lifecycle Hooks

Implement these interfaces in your component or directive class to tap into its lifecycle. Angular calls each hook at a specific time:

HookDescription
ngOnChanges()Called when input properties change.
ngOnInit()Called once after the first ngOnChanges.
ngDoCheck()Custom change-detection logic.
ngAfterContentInit()After projecting external content.
ngAfterContentChecked()After every check of projected content.
ngAfterViewInit()After initializing the component’s views and child views.
ngAfterViewChecked()After every check of the component’s views and child views.
ngOnDestroy()Cleanup before Angular destroys the directive or component.

8. Pipes

Pipes transform data in templates:

  • Built-in: DatePipe, CurrencyPipe, DecimalPipe, SlicePipe, etc.

  • Custom: Create with @Pipe({ name: 'myPipe', pure: true }) and implement transform(value, ...args).

9. Change Detection Strategies

  • Default Angular checks all components every time any asynchronous event occurs.

  • OnPush Only checks when input references change or events originate inside the component.

Quick Reference Table

CategoryKey Decorators/Features
Modules@NgModule
Components@Component, Templates, Content Projection
Directives@Directive, Structural (*ngIf, *ngFor), Attribute
Pipes@Pipe
DI@Injectable, Providers, Injection Tokens
Data BindingInterpolation, [ ], ( ), [( )], #refs
Events@Output, EventEmitter, @HostListener
Host Interaction@HostBinding
Querying@ViewChild, @ViewChildren, @ContentChild, @ContentChildren
LifecycleOnInit, OnChanges, AfterViewInit, OnDestroy, etc.
Change DetectionDefault, ChangeDetectionStrategy.OnPush

This roundup covers the essentials you mentioned—@Injectable, @Component, @Input, @Output, EventEmitter, event binding, and @Directive—plus all the core Ng decorators, binding syntaxes, lifecycle hooks, and advanced query APIs. Dive into each section in your code editor: try building tiny examples (a custom pipe, a structural directive, a host listener) to see exactly how Angular wires them together under the hood.

Can you provide examples for each Angular method?

Angular Examples for Common Decorators, Bindings, and Directives

@Injectable

The @Injectable decorator marks a class as available for dependency injection. It lets Angular’s injector know how to create instances of the class when other classes request it. By registering a service with the providedIn root scope, it becomes a singleton across the entire application.

ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class LoggerService {
  log(message: string): void {
    console.log(`[Logger] ${message}`);
  }
}

To consume this service, inject it into a component or another service:

ts
import { Component, OnInit } from '@angular/core';
import { LoggerService } from './logger.service';

@Component({
  selector: 'app-root',
  template: `<h1>Check the console</h1>`
})
export class AppComponent implements OnInit {
  constructor(private logger: LoggerService) {}

  ngOnInit() {
    this.logger.log('AppComponent initialized');
  }
}

@Component

The @Component decorator defines a new UI component by attaching metadata—template, styles, and selector—to a class. This is the core building block for any Angular application.

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

@Component({
  selector: 'app-user-card',
  template: `
    <div class="card">
      <h2>{{ name }}</h2>
      <p>Age: {{ age }}</p>
    </div>
  `,
  styles: [`
    .card { border: 1px solid #ccc; padding: 1rem; border-radius: 4px; }
  `]
})
export class UserCardComponent {
  name = 'Alice';
  age = 29;
}

Use the selector <app-user-card></app-user-card> in any parent template to render the component.

@Input

The @Input decorator allows a parent component to bind values into a child component’s property. It makes the property public and bindable via property binding syntax.

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

@Component({
  selector: 'app-child',
  template: `<p>Message from parent: {{ message }}</p>`
})
export class ChildComponent {
  @Input() message!: string;
}
html
<!-- parent.component.html -->
<app-child [message]="parentMessage"></app-child>

When parentMessage changes in the parent class, Angular updates ChildComponent.message automatically.

@Output and EventEmitter

The @Output decorator and EventEmitter class let a child component emit events that a parent can listen to. It’s the primary way of sending data upward in the component tree.

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

@Component({
  selector: 'app-child-button',
  template: `<button (click)="notifyParent()">Notify Parent</button>`
})
export class ChildButtonComponent {
  @Output() clicked = new EventEmitter<void>();

  notifyParent() {
    this.clicked.emit();
  }
}
html
<!-- parent.component.html -->
<app-child-button (clicked)="onChildClick()"></app-child-button>

The parent’s onChildClick() method is invoked whenever the child’s button is clicked.

Event Binding

Event binding connects DOM events (click, input, mouseover) to component methods. The syntax (eventName)="handler($event)" subscribes to the event and forwards its payload.

ts
// app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <input (input)="onInputChange($event)" placeholder="Type something" />
    <p>You typed: {{ text }}</p>
  `
})
export class AppComponent {
  text = '';

  onInputChange(event: Event) {
    const input = event.target as HTMLInputElement;
    this.text = input.value;
  }
}

When the user types in the input field, the onInputChange method updates the text property in real time.

Creating a Custom Directive

Directives let you attach behavior to elements. An attribute directive modifies the visual appearance or behavior of its host element.

ts
import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  @Input('appHighlight') highlightColor = 'yellow';

  constructor(private el: ElementRef) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.el.nativeElement.style.backgroundColor = this.highlightColor;
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.el.nativeElement.style.backgroundColor = '';
  }
}

Use it like this:

html
<p appHighlight="lightblue">Hover to see highlight!</p>

The paragraph’s background toggles between transparent and lightblue on mouse enter/leave.

Additional Angular Features You Might Have Missed

  • Lifecycle Hooks: ngOnInit, ngOnDestroy, ngAfterViewInit, etc., let you tap into key moments in a component’s lifespan.

  • Pipes: Built-in (date, uppercase) or custom transforms data in templates ({{ value | currency }}).

  • Services & Modules: Organize features (NgModule) and encapsulate business logic (@Injectable).

  • Routing Guards & Resolvers: Protect routes (CanActivate) or preload data before navigation (Resolve).

Each of these plays a crucial role in building maintainable, scalable Angular applications. Let me know if you’d like code examples for any of these too!

No comments:

Post a Comment

starter ASP.NET Core Web API project with example

Starter ASP.NET Core Web API project that follows all the best practices listed above. 🛠️ Starter Project Overview We’ll build a Produc...

Best for you