In Angular, the input() function creates signal-based component inputs that update automatically when their values change. These inputs are read-only signals that can be accessed in the component’s template or class using the signal getter syntax.
import { Component, input } from '@angular/core';@Component({selector: 'app-child',template: `<p>Value: {{ value() }}</p>`})export class ChildComponent {value = input<number>();}@Component({selector: 'app-parent',template: `<app-child [value]="10" />`})export class ParentComponent {}
model() FunctionIn Angular, the model() function creates a special signal that enables two-way data binding by combining input and output functionality. Changes can flow both from parent to child and from child back to parent.
import { Component, model } from '@angular/core';// Child component@Component({selector: 'app-child',template: '<button (click)="increment()">Increment</button>'})export class ChildComponent {value = model<number>(0);increment() {this.value.update(val => val + 1);}}// Parent Component@Component({selector: 'app-parent',template: '<app-child [(value)]="parentValue"></app-child>'})export class ParentComponent {parentValue = signal(10);}
When using Angular, choose between parent-child communication for related components and service-based communication for broader data sharing. The decision depends on the component relationship and how widely the data needs to be accessed or modified. Parent-child communication is often simpler but is limited to direct interactions, while service-based methods allow for more complex, global data sharing across different components.
Angular components can communicate through direct parent-child relationships using Signal inputs and model signals. Signals provide a modern, reactive way to pass data from parent to child (inputs) and enable two-way binding through model signals.
// Child Componentimport { Component, input, model } from '@angular/core';@Component({selector: 'app-child',template: `<button (click)="incrementCount()">Increment</button><p>Count: {{ count() }}</p><p>Label: {{ label() }}</p>`})export class ChildComponent {// Signal input - receives data from parent (read-only)label = input<string>('default label');// Model signal - two-way binding with parentcount = model<number>(0);incrementCount() {this.count.set(this.count() + 1);}}// Parent Componentimport { Component, signal } from '@angular/core';@Component({selector: 'app-parent',template: `<app-child[label]="'Counter'"[(count)]="parentCount()"></app-child><p>Parent sees count: {{ parentCount() }}</p>`})export class ParentComponent {parentCount = signal(0);}
Services enable communication between unrelated components by providing a shared reactive state across the application. This decouples components and allows them to exchange data and events without direct parent-child relationships.
// Shared Serviceimport { Injectable, Component, inject, signal } from '@angular/core';@Injectable({ providedIn: 'root' })export class DataService {message = signal<string>('');updateMessage(msg: string) {this.message.set(msg);}}// Component A - Updates shared state@Component({selector: 'app-component-a',template: `<button (click)="dataService.updateMessage('Hello')">Send</button>`})export class ComponentA {dataService = inject(DataService);}// Component B - Reads shared state@Component({selector: 'app-component-b',template: `<p>{{ dataService.message() }}</p>`})export class ComponentB {dataService = inject(DataService);}
In Angular, services encapsulate reusable functionality, allowing for centralized logic that can be shared across multiple components. This promotes better code organization and maintainability and reduces redundancy within the application.
@Injectable Decorator in AngularThe @Injectable decorator designates a class as a service in Angular, allowing Angular to manage its creation and distribution.
import { Injectable } from '@angular/core';@Injectable({providedIn: 'root',})export class MyService {// Service logic}
root ProviderIn Angular, setting providedIn: 'root' in the @Injectable decorator registers the service with the root injector, making it available throughout the entire application as a single shared instance.
@Injectable({providedIn: 'root'})export class MyService { }
Angular allows the injection of services into components to enable functionality. The inject() method enables service injection directly within the component’s class body, making services immediately available for use. Once injected, components gain access to the service’s shared state and methods, allowing multiple components to work with the same data.
import { Component, inject } from '@angular/core';import { UserService } from './user.service';@Component({selector: 'app-profile',template: `<p>Welcome, {{ userService.currentUser().name }}</p>`})export class ProfileComponent {userService = inject(UserService);}@Component({selector: 'app-dashboard',template: `<p>User ID: {{ userService.currentUser().id }}</p>`})export class DashboardComponent {userService = inject(UserService);}
In Angular, signals are used to manage reactive state by storing a value and automatically updating any dependent components or views when the value changes.
import { WritableSignal, signal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);increment() {this.count.update(value => value + 1);}}
signal() FunctionIn Angular, the signal() function is used to create a signal with an initial value that can be updated and observed reactively.
import { signal, WritableSignal } from '@angular/core';export class ExampleComponent {count: WritableSignal<number> = signal(0);increment() {this.count.update(n => n + 1);}}