Decorators

Decorators are design patterns used to isolate the modification or decoration of a class without modifying the source code.

There are several built-in decorators in Angular, including:

  • @Component
  • @Directive
  • @Injectable
  • @Pipe
  • @NgModule
  • @Input
  • @Output
  • @HostListener
  • @ContentChild
  • @ContentChildren
  • @ViewChild
  • @ViewChildren

Component

The @Component decorator is used to define a new component in Angular.

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

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

export class AppComponent {
  title = 'My App';
}
<h1>{{ title }}</h1>
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})

export class AppModule {}

Directive

The @Directive decorator is used to define a new directive in Angular.

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

@Directive({
  selector: '[appCustomDirective]',
})

export class CustomDirective {
  constructor(private el: ElementRef) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight('yellow');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}
<div appCustomDirective>
  This element will have a yellow background when the mouse is over it.
</div>
import { NgModule } from '@angular/core';

import { CustomDirective } from './custom.directive';

@NgModule({
  declarations: [CustomDirective],
})

export class AppModule {}

Injectable

The @Injectable decorator is used to define a new service in Angular.

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

@Injectable
export class DataService {
  getData() {
    return 'Hello, world!';
  }
}
import { Component } from '@angular/core';
import { DataService } from './data.service';

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

export class AppComponent {
  data: string;

  constructor(private dataService: DataService) {
    this.data = this.dataService.getData();
  }
}
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  providers: [DataService],
})

export class AppModule {}

Pipe

The @Pipe decorator is used to define a new pipe in Angular.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'customPipe',
})

export class CustomPipe implements PipeTransform {
  transform(value: any, args?: any): any {
    return value;
  }
}
<h1>{{ data | customPipe }}</h1>
import { NgModule } from '@angular/core';

import { CustomPipe } from './custom.pipe';

@NgModule({
  declarations: [CustomPipe],
})

export class AppModule {}

NgModule

The @NgModule decorator is used to define a new module in Angular.

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

@NgModule({
  imports: [],
  declarations: [],
  providers: [],
  bootstrap: [],
})

export class AppModule {}
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})

export class AppModule {}

Input

The @Input decorator is used to pass data from a parent component to a child component.

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

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

  ngOnInit() {}

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

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css'],
})
export class ParentComponent implements OnInit {
  parentMessage = 'Hello from the parent component!';
  constructor() {}

  ngOnInit() {}
}
<p>{{ message }}</p>
<app-child [message]="parentMessage"></app-child>
<h1>@Input Example</h1>
<app-parent></app-parent>
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { RouterModule } from '@angular/router';
import { ChildComponent } from './child/child.component';
import { ParentComponent } from './parent/parent.component';

@NgModule({
  imports: [BrowserModule, FormsModule, RouterModule],
  declarations: [AppComponent, ChildComponent, ParentComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}

Output

The @Output decorator is used to pass data from a child component to a parent component.

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

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

  constructor() {}

  ngOnInit() {}

  sendMessage() {
    this.messageEvent.emit('Hello from the child component!');
  }
}
import { Component, OnInit } from '@angular/core';

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

  ngOnInit() {}

  handleMessage(message: string) {
    console.log(message);
  }
}
<button (click)="sendMessage()">Send message</button>
<app-child (messageEvent)="handleMessage($event)"></app-child>
<h1>@Output Decorator Example</h1>
<app-parent></app-parent>

HostListener

The @HostListener decorator is used to listen for events on the host element of a directive or component.

<h1>@HostListener Decorator Example</h1>
<p>Click the host element to trigger the 'click' event.</p>
import { Component, HostListener } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  @HostListener('click')
  onClick() {
    console.log('The host element was clicked!');
  }
}

contentChild & contentChildren

The @ContentChild and @ContentChildren decorators are used to query for content children in the component's view.

import {
  Component,
  ContentChild,
  ContentChildren,
  ElementRef,
  OnInit,
  QueryList,
} from '@angular/core';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css'],
})
export class ParentComponent implements OnInit {
  @ContentChild('childButton1', { static: true }) childButton1: ElementRef;
  @ContentChildren('childButton2') childButtons2: QueryList<ElementRef>;

  ngAfterContentInit() {
    console.log(this.childButton1.nativeElement.textContent);
    this.childButtons2.forEach((button) => {
      console.log(button.nativeElement.textContent);
    });
  }

  constructor() {}

  ngOnInit() {}
}
<ng-content></ng-content>
<h1>@ContentChild Decorator Example</h1>
<app-parent></app-parent>

viewChild & viewChildren

The @ViewChild and @ViewChildren decorators are used to query for view children in the component's view.

import { Component, ElementRef, QueryList, ViewChild, ViewChildren } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  @ViewChild('childButton1', { static: true }) childButton1: ElementRef;
  @ViewChildren('childButton2') childButtons2: QueryList<ElementRef>;

  ngAfterViewInit() {
    console.log(this.childButton1.nativeElement.textContent);
    this.childButtons2.forEach(button => {
      console.log(button.nativeElement.textContent);
    });
  }
}
<h1>@viewChild & @viewChildren Example</h1>
<button #childButton1>Button 1</button>
<button #childButton2>Button 2</button>