Introducció
L'injecció de dependències (DI) és un patró de disseny fonamental en Angular que permet gestionar les dependències entre els diferents components, serveis i altres entitats de l'aplicació de manera eficient i modular. Aquest patró facilita la reutilització del codi, la prova i el manteniment de l'aplicació.
Conceptes clau
- Dependència: Un objecte que una classe necessita per funcionar.
- Injecció de dependències: El procés de proporcionar les dependències necessàries a una classe des de fora, en lloc de crear-les dins de la classe.
- Inversió de control (IoC): Un principi de disseny on el control de la creació d'objectes es transfereix a un contenidor o marc, com Angular.
Com funciona la injecció de dependències a Angular
- Proveïdors: Defineixen com crear una instància d'una dependència. Es poden registrar a nivell de component, mòdul o aplicació.
- Injecció: Angular injecta les dependències necessàries en els constructors de les classes.
Exemple pràctic
Pas 1: Crear un servei
Primer, crearem un servei que serà la nostra dependència.
// fitxer: src/app/logger.service.ts import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class LoggerService { log(message: string) { console.log(`LoggerService: ${message}`); } }
Pas 2: Injectar el servei en un component
Ara, injectarem el LoggerService
en un component.
// fitxer: src/app/app.component.ts import { Component } from '@angular/core'; import { LoggerService } from './logger.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor(private logger: LoggerService) { this.logger.log('AppComponent initialized'); } }
Explicació del codi
- @Injectable: El decorador
@Injectable
indica que la classeLoggerService
pot ser injectada com una dependència. El paràmetreprovidedIn: 'root'
fa que el servei estigui disponible a tota l'aplicació. - Constructor: El constructor del
AppComponent
rep una instància delLoggerService
com a paràmetre. Angular s'encarrega de crear aquesta instància i injectar-la.
Jerarquia d'injecció
Angular permet definir proveïdors a diferents nivells de l'aplicació, creant una jerarquia d'injecció:
- A nivell de mòdul: Els serveis definits en un mòdul estan disponibles per a tots els components d'aquest mòdul.
- A nivell de component: Els serveis definits en un component estan disponibles només per a aquest component i els seus fills.
Exemple de jerarquia d'injecció
// fitxer: src/app/parent/parent.component.ts import { Component } from '@angular/core'; import { LoggerService } from '../logger.service'; @Component({ selector: 'app-parent', templateUrl: './parent.component.html', styleUrls: ['./parent.component.css'], providers: [LoggerService] // Proveïdor a nivell de component }) export class ParentComponent { constructor(private logger: LoggerService) { this.logger.log('ParentComponent initialized'); } }
En aquest exemple, LoggerService
serà una instància diferent per a ParentComponent
i els seus components fills, en comparació amb la instància a nivell d'aplicació.
Exercici pràctic
Objectiu
Crear un servei que gestioni missatges i injectar-lo en diversos components per mostrar missatges diferents.
Passos
- Crear el servei
MessageService
:
// fitxer: src/app/message.service.ts import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class MessageService { private messages: string[] = []; add(message: string) { this.messages.push(message); } clear() { this.messages = []; } getMessages(): string[] { return this.messages; } }
- Crear dos components que utilitzin
MessageService
:
// fitxer: src/app/first/first.component.ts import { Component } from '@angular/core'; import { MessageService } from '../message.service'; @Component({ selector: 'app-first', templateUrl: './first.component.html', styleUrls: ['./first.component.css'] }) export class FirstComponent { constructor(private messageService: MessageService) { this.messageService.add('FirstComponent initialized'); } get messages() { return this.messageService.getMessages(); } }
// fitxer: src/app/second/second.component.ts import { Component } from '@angular/core'; import { MessageService } from '../message.service'; @Component({ selector: 'app-second', templateUrl: './second.component.html', styleUrls: ['./second.component.css'] }) export class SecondComponent { constructor(private messageService: MessageService) { this.messageService.add('SecondComponent initialized'); } get messages() { return this.messageService.getMessages(); } }
- Mostrar els missatges en els components:
<!-- fitxer: src/app/first/first.component.html --> <div> <h2>First Component</h2> <ul> <li *ngFor="let message of messages">{{ message }}</li> </ul> </div>
<!-- fitxer: src/app/second/second.component.html --> <div> <h2>Second Component</h2> <ul> <li *ngFor="let message of messages">{{ message }}</li> </ul> </div>
Solució
En aquest exercici, hem creat un servei MessageService
que gestiona una llista de missatges. Aquest servei s'ha injectat en dos components (FirstComponent
i SecondComponent
), que afegeixen missatges a la llista i els mostren.
Resum
- L'injecció de dependències és un patró de disseny que facilita la gestió de dependències en una aplicació Angular.
- Angular proporciona un sistema d'injecció de dependències que permet definir proveïdors a diferents nivells (aplicació, mòdul, component).
- Els serveis es poden injectar en components i altres serveis mitjançant constructors.
- La jerarquia d'injecció permet tenir diferents instàncies de serveis en diferents parts de l'aplicació.
Amb aquests coneixements, estàs preparat per gestionar dependències de manera eficient en les teves aplicacions Angular.
Curs d'Angular
Mòdul 1: Introducció a Angular
- Què és Angular?
- Configuració de l'entorn de desenvolupament
- Arquitectura d'Angular
- Primera aplicació Angular
Mòdul 2: Components d'Angular
- Comprendre els components
- Crear components
- Plantilles de components
- Estils de components
- Interacció de components
Mòdul 3: Enllaç de dades i directives
- Interpolació i enllaç de propietats
- Enllaç d'esdeveniments
- Enllaç de dades bidireccional
- Directives integrades
- Directives personalitzades
Mòdul 4: Serveis i injecció de dependències
Mòdul 5: Enrutament i navegació
Mòdul 6: Formularis a Angular
Mòdul 7: Client HTTP i observables
- Introducció al client HTTP
- Fer sol·licituds HTTP
- Gestionar respostes HTTP
- Utilitzar observables
- Gestió d'errors
Mòdul 8: Gestió d'estat
- Introducció a la gestió d'estat
- Utilitzar serveis per a la gestió d'estat
- NgRx Store
- NgRx Effects
- NgRx Entity
Mòdul 9: Proves a Angular
- Proves unitàries
- Proves de components
- Proves de serveis
- Proves de cap a cap
- Simulació de dependències
Mòdul 10: Conceptes avançats d'Angular
- Angular Universal
- Optimització del rendiment
- Internacionalització (i18n)
- Tubs personalitzats
- Animacions d'Angular