En aquest tema, aprendrem com els components d'Angular poden comunicar-se entre ells. La interacció entre components és essencial per construir aplicacions Angular complexes i ben organitzades. Explorarem diverses tècniques per compartir dades i esdeveniments entre components.
Objectius
- Entendre com passar dades de components pare a components fill.
- Aprendre a emetre esdeveniments des de components fill a components pare.
- Utilitzar serveis per compartir dades entre components no relacionats.
Passar dades de components pare a components fill
@Input Decorator
El decorador @Input
permet que un component pare passi dades a un component fill.
Exemple
- Component Pare (parent.component.ts)
import { Component } from '@angular/core'; @Component({ selector: 'app-parent', template: ` <h1>Component Pare</h1> <app-child [childMessage]="parentMessage"></app-child> ` }) export class ParentComponent { parentMessage = "Hola des del component pare!"; }
- Component Fill (child.component.ts)
import { Component, Input } from '@angular/core'; @Component({ selector: 'app-child', template: ` <h2>Component Fill</h2> <p>{{ childMessage }}</p> ` }) export class ChildComponent { @Input() childMessage: string; }
Explicació
- El component pare (
ParentComponent
) defineix una propietatparentMessage
i la passa al component fill (ChildComponent
) utilitzant la vinculació de propietats ([childMessage]="parentMessage"
). - El component fill (
ChildComponent
) rep aquesta dada a través del decorador@Input
.
Emetre esdeveniments des de components fill a components pare
@Output Decorator i EventEmitter
El decorador @Output
i la classe EventEmitter
permeten que un component fill emeti esdeveniments que poden ser escoltats pel component pare.
Exemple
- Component Pare (parent.component.ts)
import { Component } from '@angular/core'; @Component({ selector: 'app-parent', template: ` <h1>Component Pare</h1> <app-child (messageEvent)="receiveMessage($event)"></app-child> <p>Missatge rebut: {{ message }}</p> ` }) export class ParentComponent { message: string; receiveMessage($event) { this.message = $event; } }
- Component Fill (child.component.ts)
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-child', template: ` <h2>Component Fill</h2> <button (click)="sendMessage()">Envia Missatge</button> ` }) export class ChildComponent { @Output() messageEvent = new EventEmitter<string>(); sendMessage() { this.messageEvent.emit('Hola des del component fill!'); } }
Explicació
- El component fill (
ChildComponent
) defineix unEventEmitter
amb el decorador@Output
. - Quan es fa clic al botó, el mètode
sendMessage
emet un esdeveniment amb un missatge. - El component pare (
ParentComponent
) escolta aquest esdeveniment i executa el mètodereceiveMessage
, que actualitza la propietatmessage
.
Compartir dades entre components no relacionats
Utilitzar Serveis
Els serveis són una manera eficient de compartir dades entre components que no tenen una relació pare-fill.
Exemple
- Servei (data.service.ts)
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataService { private messageSource = new BehaviorSubject<string>("Missatge inicial"); currentMessage = this.messageSource.asObservable(); changeMessage(message: string) { this.messageSource.next(message); } }
- Component A (component-a.component.ts)
import { Component } from '@angular/core'; import { DataService } from '../data.service'; @Component({ selector: 'app-component-a', template: ` <h1>Component A</h1> <button (click)="newMessage()">Canvia Missatge</button> ` }) export class ComponentA { constructor(private dataService: DataService) { } newMessage() { this.dataService.changeMessage("Hola des del Component A!"); } }
- Component B (component-b.component.ts)
import { Component, OnInit } from '@angular/core'; import { DataService } from '../data.service'; @Component({ selector: 'app-component-b', template: ` <h1>Component B</h1> <p>{{ message }}</p> ` }) export class ComponentB implements OnInit { message: string; constructor(private dataService: DataService) { } ngOnInit() { this.dataService.currentMessage.subscribe(message => this.message = message); } }
Explicació
- El servei (
DataService
) utilitzaBehaviorSubject
per mantenir i emetre l'estat actual del missatge. - El
ComponentA
canvia el missatge cridant al mètodechangeMessage
del servei. - El
ComponentB
subscriu alcurrentMessage
del servei i actualitza la seva propietatmessage
quan el missatge canvia.
Exercicis Pràctics
Exercici 1: Passar dades de pare a fill
- Crea un component pare que tingui una propietat
parentData
amb el valor "Dades del pare". - Crea un component fill que mostri el valor de
parentData
passat des del component pare.
Solució
- Component Pare
import { Component } from '@angular/core'; @Component({ selector: 'app-parent', template: ` <h1>Component Pare</h1> <app-child [childData]="parentData"></app-child> ` }) export class ParentComponent { parentData = "Dades del pare"; }
- Component Fill
import { Component, Input } from '@angular/core'; @Component({ selector: 'app-child', template: ` <h2>Component Fill</h2> <p>{{ childData }}</p> ` }) export class ChildComponent { @Input() childData: string; }
Exercici 2: Emetre esdeveniments de fill a pare
- Crea un component fill que tingui un botó que emeti un esdeveniment amb el missatge "Missatge del fill" quan es fa clic.
- Crea un component pare que escolti aquest esdeveniment i mostri el missatge rebut.
Solució
- Component Pare
import { Component } from '@angular/core'; @Component({ selector: 'app-parent', template: ` <h1>Component Pare</h1> <app-child (childEvent)="receiveMessage($event)"></app-child> <p>Missatge rebut: {{ message }}</p> ` }) export class ParentComponent { message: string; receiveMessage($event) { this.message = $event; } }
- Component Fill
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-child', template: ` <h2>Component Fill</h2> <button (click)="sendMessage()">Envia Missatge</button> ` }) export class ChildComponent { @Output() childEvent = new EventEmitter<string>(); sendMessage() { this.childEvent.emit('Missatge del fill'); } }
Resum
En aquesta secció, hem après com els components d'Angular poden comunicar-se entre ells utilitzant @Input
per passar dades de pare a fill, @Output
i EventEmitter
per emetre esdeveniments de fill a pare, i serveis per compartir dades entre components no relacionats. Aquestes tècniques són fonamentals per construir aplicacions Angular modulars i ben organitzades.
Curs d'Angular 2+
Mòdul 1: Introducció a Angular
- Què és Angular?
- Configuració de l'entorn de desenvolupament
- La teva primera aplicació Angular
- Arquitectura d'Angular
Mòdul 2: Conceptes bàsics de TypeScript
- Introducció a TypeScript
- Variables i tipus de dades en TypeScript
- Funcions i funcions fletxa
- Classes i interfícies
Mòdul 3: Components i plantilles
Mòdul 4: Directives i pipes
Mòdul 5: Serveis i injecció de dependències
Mòdul 6: Enrutament i navegació
Mòdul 7: Formularis en Angular
Mòdul 8: Client HTTP i observables
- Introducció al client HTTP
- Realització de sol·licituds HTTP
- Gestió de respostes HTTP
- Ús d'observables