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>