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 propietatparentMessagei 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 unEventEmitteramb el decorador@Output. - Quan es fa clic al botó, el mètode
sendMessageemet 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) utilitzaBehaviorSubjectper mantenir i emetre l'estat actual del missatge. - El
ComponentAcanvia el missatge cridant al mètodechangeMessagedel servei. - El
ComponentBsubscriu alcurrentMessagedel servei i actualitza la seva propietatmessagequan el missatge canvia.
Exercicis Pràctics
Exercici 1: Passar dades de pare a fill
- Crea un component pare que tingui una propietat
parentDataamb el valor "Dades del pare". - Crea un component fill que mostri el valor de
parentDatapassat 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
