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 importingFormsModule
orReactiveFormsModule
.
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 viaEventEmitter
.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:
Structural Directives Change DOM layout by adding, removing, or manipulating elements.
*ngIf
*ngFor
*ngSwitch
Attribute Directives Change the appearance or behavior of an element.
Built-in:
[ngClass]
,[ngStyle]
,ngModel
Custom: Use
@Directive({ selector: '[yourDirective]' })
and injectElementRef
orRenderer2
.
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:
Hook | Description |
---|---|
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 implementtransform(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
Category | Key Decorators/Features |
---|---|
Modules | @NgModule |
Components | @Component , Templates, Content Projection |
Directives | @Directive , Structural (*ngIf , *ngFor ), Attribute |
Pipes | @Pipe |
DI | @Injectable , Providers, Injection Tokens |
Data Binding | Interpolation, [ ] , ( ) , [( )] , #refs |
Events | @Output , EventEmitter , @HostListener |
Host Interaction | @HostBinding |
Querying | @ViewChild , @ViewChildren , @ContentChild , @ContentChildren |
Lifecycle | OnInit , OnChanges , AfterViewInit , OnDestroy , etc. |
Change Detection | Default, 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.
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.
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:
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.
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.
// 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;
}
<!-- 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.
// 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();
}
}
<!-- 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.
// 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.
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:
<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