web-dev-qa-db-fra.com

meilleures pratiques de communication avec les enfants parents dans Angular

J'essaie de devenir meilleur en Angular et je veux connaître les meilleures pratiques entre la communication enfant-parent. Mon application actuelle sur laquelle je veux travailler est sur Angular 6. Je sais que je peux communiquer entre les composants parent-enfant en utilisant @ViewChild, @Output ou en créant un service. Y a-t-il une autre façon de faire la communication? sinon lequel de ces 3 est le meilleur et pourquoi?

Voici un exemple simple:

HTML enfant

<button (click)="onLinkedClicked();">Click me</button>

TS enfant

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
.
.
.
export class showcaseMenuComponent implements OnInit {
    @Output() public linkedClicked = new EventEmitter<String>();

    constructor() {}

    onLinkedClicked() {
        console.log('on click child');
        this.linkedClicked.emit('collapsed');
    }
}

HTML parent

<showcase-menu #topNavMenu 
               [showBranding]="false"
               [showSearch]= "false"  
               (linkedClicked)="linkToggler($event)">. 
</showcase-menu>

TS parent

.
.
.
 navMenuState: string;
.
.
.
  linkToggler($event) {
    console.log("partent");
    this.navMenuState = $event;
  }
5
devpato

Évidemment, cela dépend de ce que vous voulez faire.

@ Input

En utilisant @Input, Vous passez directement un paramètre à un composant enfant. De plus, vous couplez des composants en les mettant l'un dans l'autre. Cette approche est utile et simple.

C'est une bonne approche lorsque vous voulez vous assurer qu'un composant enfant est intégré dans un composant parent qui partage un objet particulier et que vous n'avez pas à vous soucier des mécanismes de synchronisme.

Cela signifie que si vous modifiez une propriété de l'objet, la référence de l'objet est toujours la même, elle est donc mise à jour en parent et en composant. Mais si vous modifiez la référence d'un objet (par exemple, instancier un nouveau ou récupérez un nouvel objet par un service distant) dans un composant, l'autre ne peut pas détecter le changement d'objet, vous aurez donc un désalignement des données.

@ Sortie

En utilisant @Output, Vous émettez un événement vers le haut, donc cette approche est utile lorsque vous souhaitez communiquer au parent que quelque chose s'est produit. L'échange de données est possible mais ce n'est pas l'objet de la chose.

Le focus est que quelque chose est arrivé, par exemple dans un assistant, vous pouvez avoir une étape et chaque étape peut informer le composant parent que cette étape particulière est terminée. Le parent n'a pas besoin de savoir comment cela s'est produit, mais seulement cela s'est produit pour qu'il puisse passer à l'étape suivante.

@ ViewChild

En utilisant @ViewChild, Vous obtenez la référence du composant enfant dans le composant parent.

Vous forcez le parent à faire fonctionner un composant enfant particulier en mélangeant sa logique.

Cela est utile lorsque vous souhaitez appeler une méthode du composant enfant dans le composant parent.

En utilisant l'exemple de l'assistant, vous pouvez penser à cette situation:

  • nous avons 3 étapes
  • La 3ème étape se termine et émet un événement @Output Au parent
  • le parent attrape l'événement et essaie de sauvegarder les données
  • enregistrement des données ok => le parent indique au composant de la dernière étape d'afficher un message réussi ou
  • échec de l'enregistrement des données => le parent indique au composant de la dernière étape d'afficher un message d'échec

Service

En utilisant un service externe, vous centralisez les données en un seul objet externe chargé de gérer et de mettre à jour les données.

Il s'agit d'une bonne approche pour les situations dans lesquelles les données peuvent être récupérées à partir de services distants ou les références d'objets de données peuvent être réaffectées.

De plus, cette approche vous permet de découpler tous vos composants les uns des autres. Ils peuvent travailler sans se soucier des comportements des autres.

En général, Subject est utilisé dans la communication de service.

Vous pouvez trouver doc ici

Objet VS @Output

Subject utilise une approche basée sur les données. @Output Utilise une approche événementielle, ou mieux une approche Programmation réactive

Par conséquent, @Output Est la méthode préférée lorsque vous souhaitez communiquer qu'un événement s'est produit, Subject est l'approche préférée pour communiquer que les données sont modifiées.

Un sujet est à la fois une source de valeurs observables et un observable lui-même. Vous pouvez vous abonner à un sujet comme vous le feriez pour tout observable.

Cela signifie que vous pouvez utiliser Subject pour observer une variable ou une valeur particulière (Subject comme Observer), il détecte les changements de valeur observés et émet une sorte d'événement.

En attendant, vous pouvez avoir de nombreux autres observateurs qui observent le Subject (Subject comme Observable) en s'abonnant aux événements du sujet.

Lorsque la valeur observée du sujet change, tous les abonnés du sujet sont informés.

Un exemple pourrait être une application de billetterie. Un utilisateur charge le composant chargé d'afficher les places restantes libres. Il réfléchit à quel endroit choisir. En attendant, un autre utilisateur achète un billet, sa place n'est donc plus disponible. Le premier utilisateur devrait maintenant voir cet endroit comme indisponible, vous devez donc actualiser les données en les demandant aux services distants (peut-être avec un algorithme d'interrogation). Lorsque de nouvelles données sont récupérées, vous passez de nouvelles données dans Subject.next(). Subject détecte que la valeur observée est modifiée et informe tous ses abonnés que la valeur est modifiée. Évidemment, Subject transmet de nouvelles données aux abonnés.

9
firegloves

Dans la situation que vous avez montrée, ma préférence serait d'utiliser @Output comme vous l'avez fait.

Il est peu probable qu'un lien cliqué soit une grande préoccupation, donc je ne pense pas qu'un service ait du sens.

@ViewChild pourrait fonctionner, mais il rend le composant moins réutilisable. Si vous souhaitez réutiliser le composant enfant dans un parent différent, vous devez recopier le code.

En utilisant @Output, si vous souhaitez utiliser le composant enfant dans un autre parent, aucun code supplémentaire ne doit être copié et vous pouvez vous lier à @Output événement très facilement.

2
Vlad274

Vous pouvez soumettre à partager des données entre plusieurs composants

Créer un service

 import { Injectable } from '@angular/core';
    import {Subject} from 'rxjs/Subject';    
    @Injectable()
    export class ChildParentService {

     data=new Subject();
      constructor() { }

    }

Exemple: https://stackblitz.com/edit/child-to-parent-bntt2h

1
Chellappan வ

Utilisez la communication de service entre le parent et les enfants lorsque:

1.Vous souhaitez transmettre des données du composant parent à plusieurs composants enfants.

2. Plusieurs composants enfants ont le même EventEmitter qui sera distribué au composant parent.

0
qinmu2127