IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Angular Discussion :

Echanger des donnees entre les composants en Angular


Sujet :

Angular

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut Echanger des donnees entre les composants en Angular
    Bonjour à tous,

    j'ai une appli en angular où mon app.componet.html est le suivant

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <div class='container'>
       <div class='row'>
          <div class="col-md-6"><i class="fa fa-shopping-cart"></i><span >
            0 article <a routerLink="basket">Basket</a>&nbsp;<a routerLink="product">Product</a>&nbsp;<a routerLink="home">Home</a>
          </span></div>
       </div>
       <div class='row'>
          <router-outlet></router-outlet>
       </div>
    </div>

    est mes routes sont les suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { RouterModule, Routes, Router } from "@angular/router";
     
    import { AppComponent } from './app.component';
    import { HelloComponent } from './hello.component';
    import { ProductComponent } from './product/product.component';
    import { BannerComponent } from './banner/banner.component';
    import { HomeComponent } from './home/home.component';
     
    const routes: Routes = [
      { path: "home", component: HomeComponent },
      { path: "", component: HomeComponent },
      { path: "product", component: ProductComponent },
      { path: "banner", component: BannerComponent }
    ];
     
     
    @NgModule({
      imports:      [ BrowserModule, FormsModule, RouterModule.forRoot(routes) ],
      declarations: [ AppComponent, HelloComponent, ProductComponent, BannerComponent, HomeComponent ],
      bootstrap:    [ AppComponent ]
    })
    export class AppModule { }
    Sur la page des produits(produit.component.html), j'ai une tableau affichant les produits et leurs prix avec un bouton permettant d'ajouter le produit sélectionné dans le panier et une page panier.component.html est créé(banner.component.html)
    produit.comonent.html
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <table class="table table-striped table-borderless">
      <thead>
        <tr>
          <th scope="col"><a #categ1 [attr.data-cat]="ax" (click)="getMyCategory(categ1.dataset.cat)" routerLinkActive="active" class="btn btn-light" role="button">AXELLES</a></th>
          <th scope="col"><a #categ2 [attr.data-cat]="bret" (click)="getMyCategory(categ2.dataset.cat)" routerLinkActive="active" class="btn btn-light" role="button">BRETINIS</a></th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let prod of products.product; let index=index">
          <td class="align-middle">{{prod.name}}</td>
          <td class="align-middle">{{ prod.price}}</td>
          <td class="align-middle"><button type="button" class="btn btn-secondary">Add product to banner</button></td>
        </tr>
      </tbody>
    </table>
    produit.component.ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    import { Component, OnInit } from '@angular/core';
    import { Router } from '@angular/router';
    import { of } from 'rxjs';
    import { Observable,from } from 'rxjs';
    import { map, filter } from 'rxjs/operators';
     
     
    const CATEGORIES = [
      {id: 1, name: 'AXELLES', 
      product: [
      	{id: 1,name:"AT", price: 2.50},
      	{id: 7,name:"CUATE", price: 1.20},
      	{id: 10,name:"BART", price: 2.30},
        {id: 16,name:"TOME", price: 4.50}
     
      	]
      },
      {id: 1, name: 'BRETINIS', 
      product: [
      	{id: 5,name:"MONERTI", price: 2.50},
      	{id: 3,name:"HUNE", price: 1.20},
      	{id: 14,name:"LARUT", price: 2.30},
        {id: 19,name:"GRATE", price: 4.50}
     
      	]
      }
    ];
     
    @Component({
      selector: 'product',
      templateUrl: './product.component.html',
      styleUrls: [ './product.component.css' ]
    })
     
    export class ProductComponent implements OnInit   {
     
      products;
      ax = 'AXELLES';
      bret = 'BRETINI';
     
      constructor( private router : Router) { }
     
      ngOnInit(): void {
        this.getCategories().subscribe(data=>{
            this.products = data;
            console.log("products : ",this.products);
         },err=>{
         	console.log("Erreur retourne : ",err);
         });
      }
     
     
      getCategories() { return of(CATEGORIES); }
     
     
      getCategory(id: number | string) {
        return this.getCategories().pipe(
          // (+) before `id` turns the string into a number
          map(categories => categories.find(categorie => categorie.id === +id))
        );
      }
     
      getCategoryByName(name: string){
        return this.getCategories().pipe(
          map(categories => categories.filter(cat => cat.name === name))
        )
      }
     
      getMyCategory(catName:string) {
      	console.log("category name : "+catName);
      }
     
    }
     
    type MyArrayType = Array<{id: number, price: number, name: string}>;
    export class Category {
      constructor(public id: number,
        public name: string,
        public product: MyArrayType) { }
    }
    Ma question comment faire pour incrémenter la valeur de l'article chaque fois qu'on clique sur le bouton d'un produit donnée sur le tableau(page : produit.component.html) sachant le l'article et dans la page (app.component.html) voir code ci-dessous.

    Ensuite comment remplir la banner.component.html (listant le produit sélectioné sur un tableau par le client et lui donner la possibilité de supprimer ou d'ajouter le produit depuis la page du panier (banner.component.html), tout en mettant à jour le nombre d'article en haut de la page et sachant que cette valeur se trouve sur la page app.component.html).

    J'ai aussi créé un lien de mon code sur stackblit : http://stackblitz.com/edit/angular-ivy-4er2hh

    merci de vos réponses

  2. #2
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    il faut consulter la doc officielle ou des tutos sur la communication entre composant sur angular.

    il y a 3 techniques:
    - two way data binding: uniquement entre composant parent et enfant (dans les 2 sens)
    - par service: pour tous les composants
    - par observable/subject: pour tous les composants

    pas besoin de redux, au cas ou tu tombes dessus !

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    Salut @dukoid,

    merci pour l'éclaircissement; je pense que dans mon cas de figure, ce sera cette technique : - par observable/subject: pour tous les composants ou celle-ci par service: pour tous les composants

    pourra tu me donner en exemple un code pour m'en inspirer et aussi me donner le lien de ton tutoriel;

    merci d'avance

  4. #4
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    le tuto, je ne l'ai pas encore fini.. c'est en cours..

    voici un exemple avec les observables:
    https://reactgo.com/angular-component-communication/

    c'est facile à mettre en place
    Les observables c'est puissant et avec RxJS c'est le top !

    bien avoir le principe en tête:
    - un subject/observable est dans un service et ce dernier est disponible pour tous les composants ( ou d'autres services)
    - on émet sur un subject (observable) du service une ou des données
    - tous les composants (ou d'autres services) qui ont souscrit à cette observable reçoit la/les données..
    - ne pas oublier de se désabonner d'un subjet si on change de page (lors d'un routing)


    on trouve pleins de tuto sur les subjects et rxjs...

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    salut @dukoid,

    - j'essaie de comprendre pour l'adapter à mon cas.
    Moi je ma page product.component.html(.ts) ,app.component.html(.ts) et panier.component.html(.ts)
    mon but faire varier le nombre d'articles dans le panier de deux sortes :

    - Au niveau de product.component quand on ajoute un produit au panier en cliquant sur le bouton Ajouter au panier
    - et puis au niveau de la page panier.component quand on ajoute le nombre du produit ou on la reduit .

    Je crée un service

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
     
    import { Subject } from 'rxjs';
    import { Injectable } from '@angular/core';
     
    @Injectable({
        providedIn: 'root'
    })
     
    export class NombreArticleService {
        private subject = new Subject();
     
        sendNbArticle(nbArticle) {
            // it is used to publish data
             this.subject.next(art);
        }
        accessNbArticle() {
            return this.subject.asObservable();
        }
    }
    Comment le faire côté adapater côté app.component pour faire varier le nombre d'article quand on clique sur le bouton Ajouter au panier dans product.component.html(.ts) et aussi dans panier.component.htmhl(.ts)

    peux tu me montrer avec un petit exemple de code avec mon cas pour l'adapter.

  6. #6
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    #/model/Product.ts
    #cart.service.ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    products: Array<Product> = [];
    obsCart = subject
    
    
    fonction ajouter produit
        ajoute le produit dans products
        emit  sur obsCart  avec les données:  products
    fonction enlever produit
        enlève le produit dans products
        emit  sur obsCart  avec les données:  products

    #product.component.html
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    liste des produits  <---> le comparer avec : cart.service.products si il y a des produits qui ont été sélectionné
    si correspond donc affiché le nombre
     
    bouton +        fonction ajouter produit
    boutoin -        fonction enlever produit
    #product.component.ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    souscrit à l observable:  cart.service.obsCart
               -> met à jour la vue  avec les produits reçu de l'observable
     
    fonction ajouter produit
              cart.service. appel de la fonction ajouter produit (lequel?  nombre?)
     
    fonction ajouter produit
              cart.service.  appel de la fonction enlever produit (lequel?  nombre?)

    #cart.component.html
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    ngFor sur  cart.service.products
     
    bouton +            fonction ajouter produit
    bouton -             fonction enlever produit
    #cart.component.ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    souscrit à l observable:  cart.service.obsCart
               -> met à jour la vue avec les produits reçu de l'observable
     
    fonction ajouter produit
              cart.service. appel de la fonction ajouter produit (lequel?  nombre?)
     
    fonction ajouter produit
              cart.service.  appel de la fonction enlever produit (lequel?  nombre?)

    qu'en penses-tu ? étudie bien la question avant de te lancer !


    astuce qui vaut de l'or:
    tu peux étudier des sources sur github plus ou moins compliqués (enfin, ça parait compliqué quand on a pas les connaissances )
    https://github.com/search?q=angular+9+cart

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    Salut @dukoid,

    Quelques précisions:

    De mon côté , l'objet produit est juste defini avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    id,
    name,
    price  // pas de nb
    Ensuite si j'ai bien compris ton explication cart.service.ts est le service que je dois créer afin de communiquer avec les autres composants

    cart.service.ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    import { Subject } from 'rxjs';
    import { Injectable } from '@angular/core';
    import { Produit} from '../model/produit';
     
    @Injectable({
        providedIn: 'root'
    })
     
    export class CartService {
        products: Array<Product> = [];
        private subject = new Subject();
     
        ajouterProduit(produit:Produit) {
            this.products.push(produit)
             this.subject.next(this.products);  // c'est ça emit : emit  sur obsCart  avec les données:  products ???
        }
     
        enleverProduit(produit:Produit) {
          this.products = this.products.filter(obj => obj !== produit);
             this.subject.next(this.products);
        }
     
        accessNbArticle() {
            return this.subject.asObservable();
        }
    }
    Aussi mon product.component.html est celui ci
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <table class="table table-striped table-borderless">
      <thead>
        <tr>
          <th scope="col"><a #categ1 [attr.data-cat]="ax" (click)="getMyCategory(categ1.dataset.cat)" routerLinkActive="active" class="btn btn-light" role="button">AXELLES</a></th>
          <th scope="col"><a #categ2 [attr.data-cat]="bret" (click)="getMyCategory(categ2.dataset.cat)" routerLinkActive="active" class="btn btn-light" role="button">BRETINIS</a></th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let prod of products.product; let index=index">
          <td class="align-middle">{{prod.name}}</td>
          <td class="align-middle">{{ prod.price}}</td>
          <td class="align-middle"><button type="button" class="btn btn-secondary">Add product to banner</button></td>
        </tr>
      </tbody>
    </table>

    product.ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    import { Component, OnInit } from '@angular/core';
    import { Router } from '@angular/router';
    import { of } from 'rxjs';
    import { Observable,from } from 'rxjs';
    import { map, filter } from 'rxjs/operators';
     
     
    const CATEGORIES = [
      {id: 1, name: 'AXELLES', 
      product: [
      	{id: 1,name:"AT", price: 2.50},
      	{id: 7,name:"CUATE", price: 1.20},
      	{id: 10,name:"BART", price: 2.30},
        {id: 16,name:"TOME", price: 4.50}
     
      	]
      },
      {id: 1, name: 'BRETINIS', 
      product: [
      	{id: 5,name:"MONERTI", price: 2.50},
      	{id: 3,name:"HUNE", price: 1.20},
      	{id: 14,name:"LARUT", price: 2.30},
        {id: 19,name:"GRATE", price: 4.50}
     
      	]
      }
    ];
     
    @Component({
      selector: 'product',
      templateUrl: './product.component.html',
      styleUrls: [ './product.component.css' ]
    })
     
    export class ProductComponent implements OnInit   {
     
      products;
      ax = 'AXELLES';
      bret = 'BRETINI';
     
      constructor( private router : Router) { }
     
      ngOnInit(): void {
        this.getCategories().subscribe(data=>{
            this.products = data;
            console.log("products : ",this.products);
         },err=>{
         	console.log("Erreur retourne : ",err);
         });
      }
     
     
      getCategories() { return of(CATEGORIES); }
     
     
      getCategory(id: number | string) {
        return this.getCategories().pipe(
          // (+) before `id` turns the string into a number
          map(categories => categories.find(categorie => categorie.id === +id))
        );
      }
     
      getCategoryByName(name: string){
        return this.getCategories().pipe(
          map(categories => categories.filter(cat => cat.name === name))
        )
      }
     
      getMyCategory(catName:string) {
      	console.log("category name : "+catName);
      }
     
    }
    comment comparer le products da cart.service et le mien avant l'affichage

    et dernière question ou précision, l'affichage du compteur d'article est dans app.component.html(ts)
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <div class='container'>
       <div class='row'>
          <div class="col-md-6"><i class="fa fa-shopping-cart"></i><span >
            0 article <a routerLink="basket">Basket</a>&nbsp;<a routerLink="product">Product</a>&nbsp;<a routerLink="home">Home</a>
          </span></div>
       </div>
       <div class='row'>
          <router-outlet></router-outlet>
       </div>
    </div>

    comment modifier son t avec l'impact d'ajout d'un produit dans la page product.component.html, car si tu regarde bien, le contenu de product.component.html sera inclus dans la directive <router-outlet></router-outlet>

  8. #8
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    tu peux créer un nouveau modèle. peut être l'appeler: product-cart.ts
    avec comme propriété: id, nb

    ainsi, ce qui est échangé entre les composants et observable c'est le modèle.
    c'est toujours bien !


    pour le banner, c'est pareil.
    faut souscrire à l'observable pour récupérer les produits du panier et donc tu peux compter le nombre etc...


    quand à la comparaison liste des produits/ produits du panier
    il y a plein de façon de faire...

  9. #9
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    super @dukoid, je commence à voir le bout du tunnel.
    Tu peux me proposer un exemple pour la comparaison liste des produits/ produits du panier.

  10. #10
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    d'un coté un certains nombre de produit, tu as une liste avec: id, nbSelected
    de l'autre coté, une liste de tes produits affichés avec : id, name, price


    est ce que tu as la possibilité de mettre nbSelected dans le modèle original ? pour avoir: id, name, price, nbSelected

Discussions similaires

  1. Gestion des transactions avec les composants DOA
    Par lper dans le forum Bases de données
    Réponses: 2
    Dernier message: 01/12/2008, 16h06
  2. Echange de donnéee entre un Flash et la page le contenant
    Par ViveLesQuads dans le forum Flash
    Réponses: 2
    Dernier message: 31/10/2006, 13h40
  3. effectuer des operations sur les composants graphiques
    Par Zorgz dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 19/10/2006, 14h34
  4. Quelle solution pour partager des données entre Linux ?
    Par herzleid dans le forum Administration système
    Réponses: 5
    Dernier message: 03/04/2006, 16h19
  5. [TP] Echanger des données entre deux programmes
    Par ILIAS Raphaël dans le forum Turbo Pascal
    Réponses: 3
    Dernier message: 22/03/2005, 09h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo