Cours Angular Component Interaction
Cours Angular Component Interaction
Achref El Mouelhi
1 Introduction
2 Balise d’interaction
3 Décorateurs d’interaction
Exemple avec @Input()
Exemple avec @ViewChild()
Exemple avec @ViewChildren()
Exemple avec @ContentChild()
Exemple avec @ContentChildren()
Exemple avec @Output()
4 Variable locale et @ViewChild
5 Service, subject et interaction
Angular
M OU
un composant web Angular : ng-content
f E L @Output(), @ViewChild,
des décorateurs @Input(),
e
chr @ContentChild, @ContentChildren
@ViewChildren,
© A
M OU
un composant web Angular : ng-content
f E L @Output(), @ViewChild,
des décorateurs @Input(),
e
chr @ContentChild, @ContentChildren
@ViewChildren,
© A
Autres formes d’interaction : enfant-enfant ou parent-enfant
Angular
Avant de commencer
H I ©
Créons deux composants pere et fils
UEL
O
f E LM
Définissions une route /pere pour le composant pere
r e
Ajoutons le sélecteur du composant fils app-fils dans
ch
©A
pere.component.html
Angular
Le fichier fils.component.ts
@Component({
selector: ’app-fils’,
templateUrl: ’./fils.component.html’,
styleUrls: [’./fils.component.css’]
H I ©
})
UEL
export class FilsComponent implements OnInit {
O
constructor() { }
f E LM
ngOnInit() { }
ch r e
}
©A
Le fichier fils.component.html
<li>
Je suis un fils
</li>
Angular
Le fichier pere.component.ts
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
H I ©
})
UEL
export class PereComponent implements OnInit {
O
constructor() { }
f E LM
ngOnInit() { }
ch r e
©A
}
<ul>
<app-fils></app-fils>
<app-fils></app-fils>
<app-fils></app-fils>
</ul>
Angular
Et si on veut passer du contenu texte à notre composant enfant, on fait :
<ul>
<app-fils>John Wick</app-fils>
<app-fils>Jack Shephard</app-fils>
<app-fils>James Ford</app-fils>
H I ©
EL
</ul>
O U
f E LM
ch r e
©A
Angular
Et si on veut passer du contenu texte à notre composant enfant, on fait :
<ul>
<app-fils>John Wick</app-fils>
<app-fils>Jack Shephard</app-fils>
<app-fils>James Ford</app-fils>
H I ©
EL
</ul>
O U
f E LM
En testant le résultat est :
ch r e
©A
Je suis un fils
Je suis un fils
Je suis un fils
Angular
Angular
Angular
Remarque
H I
La balise ng-content a un attribut select qui prend comme valeur ©
UEL
O
le nom d’un attribut de n’importe quelle balise définie dans le
composant parent
f E LM
le nom d’une classe CSS
ch r e
©A
le nom d’une balise
Angular
Dans pere.component.html, on peut aussi définir des classes dont la valeur est soit
prenomContent ou nomContent
<ul>
<app-fils>
<span class=prenomContent> John </span>
<span class=nomContent> Wick </span>
</app-fils>
<app-fils>
<span class=prenomContent> Jack </span>
H I ©
EL
<span class=nomContent> Shephard </span>
</app-fils>
<app-fils>
O U
<span class=prenomContent> James </span>
f E
<span class=nomContent> Ford </span> LM
</app-fils>
ch r e
©A
</ul>
Dans pere.component.html, on peut aussi définir des classes dont la valeur est soit
prenomContent ou nomContent
<ul>
<app-fils>
<span class=prenomContent> John </span>
<span class=nomContent> Wick </span>
</app-fils>
<app-fils>
<span class=prenomContent> Jack </span>
H I ©
EL
<span class=nomContent> Shephard </span>
</app-fils>
<app-fils>
O U
<span class=prenomContent> James </span>
f E
<span class=nomContent> Ford </span> LM
</app-fils>
ch r e
©A
</ul>
Angular
<ul>
<app-fils>
<span> John Wick </span>
<a href="#"> link </a>
</app-fils>
<app-fils>
<span> Jack Shephard </span>
<a href="#"> link </a>
H I ©
</app-fils>
UEL
<app-fils>
O
LM
<span> James Ford </span>
<a href="#"> link </a>
</app-fils>
r e f E
</ul>
ch
©A
<ul>
<app-fils>
<span> John Wick </span>
<a href="#"> link </a>
</app-fils>
<app-fils>
<span> Jack Shephard </span>
<a href="#"> link </a>
H I ©
</app-fils>
UEL
<app-fils>
O
LM
<span> James Ford </span>
<a href="#"> link </a>
</app-fils>
r e f E
</ul>
ch
©A
Dans fils.component.html, on sélectionne les données selon les balises
<li>
Nom et prénom : <ng-content select="span"></ng-content>,
pour apprendre plus => <ng-content select="a"></ng-content>
</li>
Angular
Angular
Angular
H I ©
Dans cet exemple
U EL
O
LM
On définit dans fils.component.ts deux attributs ordre et
f E
villeNaissance qui seront affichés dans le template.
r e
ch
©A
@Component({
selector: ’app-fils’,
templateUrl: ’./fils.component.html’,
styleUrls: [’./fils.component.css’]
})
export class FilsComponent implements OnInit {
H I ©
EL
@Input() ordre = ’’;
@Input() villeNaissance = ’’;
O U
constructor() { }
f E LM
ngOnInit() { }
ch r e
©A
}
<li>
Je suis le {{ ordre }} fils et suis de {{ villeNaissance }}
</li>
Le fichier pere.component.ts
import { Component, OnInit } from ’@angular/core’;
import { FilsComponent } from ’../fils/fils.component’;
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
})
H I ©
EL
export class PereComponent implements OnInit {
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
nord = ’Lille’;
O U
sud = ’Marseille’;
capitale = ’Paris’;
f E LM
constructor() { }
ch r e
}
ngOnInit() { }
©A
Le fichier pere.component.html
<ul>
<app-fils [ordre]="tab[0]" [villeNaissance]="sud"></app-fils>
<app-fils [ordre]="tab[1]" [villeNaissance]="nord"></app-fils>
<app-fils [ordre]="tab[2]" [villeNaissance]="capitale"></app-fils>
</ul>
H & H: Research and Training 20 / 61
Décorateurs d’interaction Exemple avec @Input()
Angular
Le résultat est
H I ©
U
Je suis le premier fils et suis EdeL Marseille
L MetOsuis de Lille
r e f E
Je suis le deuxième fils
Je suis le c
A h
troisième fils et suis de Paris
©
Angular
@Component({
selector: ’app-fils’,
templateUrl: ’./fils.component.html’,
styleUrls: [’./fils.component.css’]
})
export class FilsComponent implements OnInit, OnChanges {
H I ©
EL
@Input() ordre: string;
@Input() villeNaissance: string;
constructor() { }
O U
ngOnInit() { }
f E LM
ch r e
ngOnChanges(changes: SimpleChanges): void { console.log(changes); }
©A
}
@Component({
selector: ’app-fils’,
templateUrl: ’./fils.component.html’,
styleUrls: [’./fils.component.css’]
})
export class FilsComponent implements OnInit, OnChanges {
H I ©
EL
@Input() ordre: string;
@Input() villeNaissance: string;
constructor() { }
O U
ngOnInit() { }
f E LM
ch r e
ngOnChanges(changes: SimpleChanges): void { console.log(changes); }
©A
}
Remarque
SimpleChanges est un objet JavaScript dont les clés sont les attributs changés et les
valeurs sont des objets SimpleChange
@Component({
selector: ’app-fils’,
templateUrl: ’./fils.component.html’,
styleUrls: [’./fils.component.css’]
})
export class FilsComponent implements OnInit, OnChanges {
H I ©
EL
@Input() ordre: string;
@Input() villeNaissance: string;
O U
LM
constructor() { }
ngOnInit() { }
r e f E
ch
ngOnChanges(changes: SimpleChanges): void {
©A
for (const key of Object.keys(changes)) {
console.log(key);
const obj = changes[key];
for (const cle of Object.keys(obj)) {
console.log(cle, obj[cle]);
}
}
}
}
Angular
Exercice
Dans pere.component.html, ajoutez deux input : un premier
pour nom et un deuxième pour ville
H I ©
EL
Dans pere.component.ts, définissez deux variables nom et un
OU
deuxième pour la ville et deux tableaux noms et villes
M
Créez autant de app-fils L
e f E que d’éléments dans noms (ou
villes)
A c hr
Chaque© fils récupère et affiche les valeurs envoyées par le
composant pere
L’utilisateur pourra ajouter un nombre indéterminé de composant
fils dans pere.
Angular
Exercice list-item
Créons deux composants list et item.
Chaque composant item reçoit le texte et sa couleur d’affichage
H I ©
EL
du composant list.
O U
Dans le composant list, on a deux zones de saisie : la première
E LM
pour le texte, la deuxième pour la couleur du texte à afficher (à
f
saisir en anglais).
ch r e
©A
En cliquant sur le bouton ajouter du composant list, un
nouveau composant item s’ajoute (s’affiche) au composant (dans
la page) avec la couleur indiquée par l’utilisateur.
L’utilisateur pourra ajouter un nombre indéterminé de texte.
Angular
Objectif
Angular
Objectif
Angular
Commençons par déclarer le composant fils comme attribut dans pere.component.ts et
le décorer avec @ViewChild()
import { Component, OnInit, ViewChild } from ’@angular/core’;
import { FilsComponent } from ’../fils/fils.component’;
@Component({
selector: ’app-pere’,
H I ©
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
U EL
O
LM
})
r e f E
export class PereComponent implements OnInit {
ch
@ViewChild(FilsComponent) fils: FilsComponent;
©A
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
nord = ’Lille’;
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() { }
}
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
})
styleUrls: [’./pere.component.css’]
H I ©
export class PereComponent implements OnInit {
U EL
O
LM
@ViewChild(FilsComponent, { static: false }) fils: FilsComponent;
r e f E
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
nord = ’Lille’;
ch
©A
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() { }
}
{ static: false } car les attributs du composant enfant sont alimentés par le père et ne
sont donc pas initialisés dans le composant.
H & H: Research and Training 29 / 61
Décorateurs d’interaction Exemple avec @ViewChild()
on ne peut accéder aux attributs d’un composant enfant non-statique qu’après initiation
de la vue
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
H I ©
})
export class PereComponent implements OnInit {
U EL
O
f E LM
@ViewChild(FilsComponent, { static: false }) fils: FilsComponent;
nord = ’Lille’;
ch r e
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
©A
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() {
console.log(this.fils.ordre);
}
}
ce code génère une erreur car le composant fils est encore indéfini.
H & H: Research and Training 30 / 61
Décorateurs d’interaction Exemple avec @ViewChild()
En mettant { static: true }, on indique qu’il ne faut plus attendre l’initiation de la vue
(fils) car ses données sont statiques
import { Component, OnInit, ViewChild } from ’@angular/core’;
import { FilsComponent } from ’../fils/fils.component’;
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
H I ©
EL
})
export class PereComponent implements OnInit {
O U
f E LM
@ViewChild(FilsComponent, { static: true }) fils: FilsComponent;
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
nord = ’Lille’;
ch r e
©A
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() {
console.log(this.fils.ordre); // affiche undefined
}
}
En mettant { static: true }, on indique qu’il ne faut plus attendre l’initiation de la vue
(fils) car ses données sont statiques
import { Component, OnInit, ViewChild } from ’@angular/core’;
import { FilsComponent } from ’../fils/fils.component’;
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
H I ©
EL
})
export class PereComponent implements OnInit {
O U
f E LM
@ViewChild(FilsComponent, { static: true }) fils: FilsComponent;
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
nord = ’Lille’;
ch r e
©A
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() {
console.log(this.fils.ordre); // affiche undefined
}
}
Affecter une valeur à ordre dans fils.component.ts et vérifier que cette valeur est
affichée à la place de undefined.
H & H: Research and Training 31 / 61
Décorateurs d’interaction Exemple avec @ViewChild()
Remettons { static: false } et indiquons qu’il faut attendre que la vue soit initiée
pour accéder aux attributs
import { Component, OnInit, ViewChild, AfterViewInit } from ’@angular/
core’;
import { FilsComponent } from ’../fils/fils.component’;
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
H I ©
EL
styleUrls: [’./pere.component.css’]
})
O
export class PereComponent implements OnInit, AfterViewInit { U
f E LM
@ViewChild(FilsComponent, { static: false }) fils: FilsComponent;
ch r e
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
©A
nord = ’Lille’;
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() { }
ngAfterViewInit(): void {
console.log(this.fils.ordre); // affiche premier
}
}
H & H: Research and Training 32 / 61
Décorateurs d’interaction Exemple avec @ViewChildren()
Angular
Objectif
Angular
Objectif
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
H I ©
EL
})
export class PereComponent implements OnInit, AfterViewInit {
O U
undefined;
f E LM
@ViewChildren(FilsComponent) fils: QueryList<FilsComponent> |
ch r e
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
©A
nord = ’Lille’;
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() { }
ngAfterViewInit(): void {
this.fils?.forEach(elt => console.log(elt));
// affiche les trois FilsComposant dans la console
}
}
H & H: Research and Training 34 / 61
Décorateurs d’interaction Exemple avec @ViewChildren()
Angular
Angular
Objectif
Angular
Objectif
Angular
Le fichier titre.component.ts
import { Component, OnInit, Input } from ’@angular/core’;
@Component({
selector: ’app-titre’,
templateUrl: ’./titre.component.html’,
styleUrls: [’./titre.component.css’]
H I ©
})
export class TitreComponent implements OnInit {
U EL
O
LM
@Input() valeur: string;
@Input() couleur: string;
constructor() { }
r e f E
ch
©A
ngOnInit() {
}
Le fichier titre.component.html
<h1 [ngStyle]="{color: couleur}">{{ valeur }}</h1>
Angular
Angular
Angular
H I ©
Dans pere.component.html, on récupère sélectionne le titre dans la balise ng-content
<ng-content select="app-titre"></ng-content>
<ul>
U EL
O
LM
<app-fils [ordre]="tab[0]" [villeNaissance]="sud"></app-fils>
e E
<app-fils [ordre]="tab[1]" [villeNaissance]="nord"></app-fils>
f
<app-fils [ordre]="tab[2]" [villeNaissance]="capitale"></app-fils>
r
</ul>
ch
©A
@Component({
selector: ’app-pere’,
templateUrl: ’./pere.component.html’,
styleUrls: [’./pere.component.css’]
H I ©
EL
})
export class PereComponent implements OnInit, AfterContentInit {
O U
TitreComponent;
f E LM
@ContentChild(TitreComponent, { static: false }) titre:
ch r e
tab: Array<string> = [’premier’, ’deuxième’, ’troisième’];
©A
nord = ’Lille’;
sud = ’Marseille’;
capitale = ’Paris’;
constructor() { }
ngOnInit() { }
ngAfterContentInit(): void {
console.log(this.titre.valeur);
}
}
H & H: Research and Training 40 / 61
Décorateurs d’interaction Exemple avec @ContentChildren()
Angular
Explication
Angular
Explication
Angular
Avant de commencer
H I ©
U EL
O
f E LM
ch r e
©A
Angular
Avant de commencer
H I ©
EL
Dans cet exemple
M OU
Chaque élément child aura un
f E L texte pour saisir une note et un bouton
champ
e
chr composant parent
pour envoyer la valeur au
Le bouton©
A
sera désactivé après envoi
Chaque fois que le composant parent reçoit une note d’un de ses fils, il
recalcule la moyenne et il l’affiche
Angular
Le fichier child.component.html
H I ©
<h6> {{ nom }} </h6>
U EL
<input type=number name=note [(ngModel)]=note>
O
<button (click)="send()" [disabled]="buttonStatus">
f E LM
Send
ch r e
©A
</button>
Angular
Le fichier child.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from ’
@angular/core’;
@Component({
selector: ’app-child’,
templateUrl: ’./child.component.html’,
H I ©
EL
styleUrls: [’./child.component.css’]
})
O U
LM
export class ChildComponent implements OnInit {
@Input() nom = ’’;
e f E
@Output() message = new EventEmitter<number>();
r
ch
note = 0;
©A
buttonStatus = false;
constructor() { }
ngOnInit(): void { }
send(): void {
this.message.emit(this.note);
this.buttonStatus = true;
}
}
H & H: Research and Training 44 / 61
Décorateurs d’interaction Exemple avec @Output()
Angular
Le fichier parent.component.ts
import { Component, OnInit } from ’@angular/core’;
@Component({
selector: ’app-parent’,
templateUrl: ’./parent.component.html’,
styleUrls: [’./parent.component.css’]
H I ©
})
export class ParentComponent implements OnInit {
U EL
O
LM
moyenne = 0;
somme = 0;
nbr = 0;
r e f E
ch
enfants = [’Wick’, ’Hoffman’, ’Abruzzi’];
©A
constructor() { }
ngOnInit(): void { }
computeAvg(note: number): void {
this.somme += note;
this.nbr++;
this.moyenne = this.somme / this.nbr;
}
}
Angular
Le fichier parent.component.html
H I ©
U E L }} </h3>
<h3> Moyenne de mes enfants {{ moyenne
<app-child *ngFor="let enfant O
L M of enfants" [nom]="
f E
enfant" (message)="computeAvg($event)">
r e
</app-child>
A ch
©
Angular
Exercice
H I ©
Le composant parent doit permettre à l’utilisateur de saisir le
U EL
nom affecté à un composant child O
f E LM
ch r e
Modifiez les composants parent et child pour qu’on puisse
calculer la moyenne d’un nombre variable de notes
©A
Angular
Exercice clavier-touche
c h clavier.
Le nombre de A
© composants touche = taille du tableau lettres.
Chaque composant touche affiche la lettre qu’il a reçue sur un bouton.
En cliquant sur ce bouton, la lettre s’affiche (à la suite des autres) dans une
balise div définie dans le composant clavier.
Angular
Exercice panier-article
H I ©
EL
Créez une interface avec les attributs id, désignation et prixUnitaire
O U
LM
Dans panier.component.ts, on considère le tableau articles donné dans
la slide suivante
r e f E
A ch
Dans panier.component.html, on affiche chaque élément de articles
dans un composant article
©
Chaque composant article contient un champ texte pour saisir une quantité
et un bouton qui permet d’envoyer l’article et la quantité au composant panier
Chaque fois qu’on clique sur le bouton ajouter d’un article, le composant
panier affiche le total
Angular
r e E
{ id: 3, description: ’écran’, prixUnitaire: 200 },
f
{ id: 4, description: ’modem’, prixUnitaire: 30 },
ch
©A
];
@Component({
O U
selector: ’app-root’,
templateUrl: ’./app.component.html’,
f E LM
ch
styleUrls: [’./app.component.css’]
r e
©A
})
export class AppComponent implements AfterViewInit {
ngAfterViewInit(): void {
this.p.nativeElement.innerHTML += ’texte ajouté depuis le composant
.ts’;
}
}
H & H: Research and Training 51 / 61
Variable locale et @ViewChild
Angular
Exercice moyenne-note
Dans le composant moyenne, on peut ajouter plusieurs composants note (en cliquant sur
un bouton ajouter)
H I ©
EL
Le composant note permet à l’utilisateur de saisir une valeur et un coefficient. Pendant la
U
O
saisie, la valeur de la moyenne (définie dans le composant moyenne) se met à jour.
E LM
Vous pouvez utiliser une interface Note avec deux attributs valeur et coefficient
f
ch r e
©A
Angular
Exercice moyenne-note
Dans le composant moyenne, on peut ajouter plusieurs composants note (en cliquant sur
un bouton ajouter)
H I ©
EL
Le composant note permet à l’utilisateur de saisir une valeur et un coefficient. Pendant la
U
O
saisie, la valeur de la moyenne (définie dans le composant moyenne) se met à jour.
E LM
Vous pouvez utiliser une interface Note avec deux attributs valeur et coefficient
f
ch r e
©A
Exercice (suite de l’exercice précédent)
Le composant note contenant la valeur min sera affiché en rouge et le composant contenant la
valeur max sera affiché en vert.
Angular
Avant de commencer
Créons trois composants container, first et second
Créons un service message
H I ©
EL
Ajoutons les deux sélecteurs app-first et app-second dans
container.component.html
M OU
E L pour le composant
Définissons une route /container
f
container
chr e
© A
Angular
Avant de commencer
Créons trois composants container, first et second
Créons un service message
H I ©
EL
Ajoutons les deux sélecteurs app-first et app-second dans
container.component.html
M OU
E L pour le composant
Définissons une route /container
f
container
chr e
© A
Contenu de app.component.html
<app-first></app-first>
<app-second></app-second>
Angular
Idée
Définir un subject dans message.service.ts H I ©
UEL
O
Injecter le service dans le constructeur de deux composants
first et second
f E LM
r e
chpour émettre les données d’un composant vers
Utiliser le service
un autre© A
Angular
Contenu de notre service
import { Injectable } from ’@angular/core’;
import { Subject } from ’rxjs’;
@Injectable({
providedIn: ’root’
H I ©
})
UEL
export class MessageService { O
private subject = new Subject<string>();
f E LM
constructor() { }
ch r e
©A
envoyerMessage(msg: string) {
this.subject.next(msg);
}
accederMessage() {
return this.subject;
}
}
H & H: Research and Training 55 / 61
Service, subject et interaction
Angular
Le fichier first.component.html
H I ©
<div>
UEL
Message : <input type=text [(ngModel)]="msg" >
O
<button (click)="ajouterMessage()">Ajouter message
f E LM
</button>
ch r e
©A
</div>
Angular
Définissons ajouterMessage() dans first.component.ts et utilisons
MessageService pour envoyer le message aux observateurs
import { Component, OnInit } from ’@angular/core’;
import { MessageService } from ’../services/message.service’;
@Component({
selector: ’app-first’,
H I ©
templateUrl: ’./first.component.html’,
styleUrls: [’./first.component.css’]
UEL
O
LM
})
export class FirstComponent implements OnInit {
r e f E
msg: string;
ch
©A
constructor(private messageService: MessageService) { }
ngOnInit() { }
ajouterMessage() {
this.messageService.envoyerMessage(this.msg);
this.msg = ’’;
}
}
Angular
@Component({
selector: ’app-second’,
templateUrl: ’./second.component.html’,
H I ©
EL
styleUrls: [’./second.component.css’]
})
export class SecondComponent implements OnInit, OnDestroy {
O U
messages = [];
f E LM
subscription: Subscription;
ch r e
©A
constructor(private messageService: MessageService) { }
ngOnInit() {
this.subscription = this.messageService.accederMessage().subscribe(
msg => this.messages.push(msg)
);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
H & H: Research and Training 59 / 61
Service, subject et interaction
Angular
Exercice
H I ©
EL
OU
On veut que l’échange entre deux composants soit bidirectionnel.
M
le L
Quand le premier envoie,E
r e f deuxième affiche et inversement.
A ch
©
Angular
Exercice
Créez deux composant tchat et participant
Définissez une route /tchat pour le composant tchat
H I ©
Le composant tchat contient un champ texte nom et un bouton
UEL
ajouter qui permet d’ajouter un nouveau composant
O
participant dans tchat
f E LM
ch r e
Chaque composant participant peut envoyer des messages à
©A
tous les autres participants
Les participants reçoivent immédiatement les messages envoyés
et les affichent
Un participant n’affiche pas ses propres messages