web-dev-qa-db-fra.com

Angular 6 Service de partage de données S'abonner non déclenché

Je dois définir la valeur dans un composant (composant A) et recevoir la valeur dans un autre composant (composant B). Le composant A et le composant B ne sont pas parents et enfants.

J'ai créé un service partagé pour partager des données entre les 2 composants. Je peux définir la valeur du composant B, mais lorsque je m'abonne pour obtenir la valeur du composant A, elle n'est pas déclenchée.

Voici ce que j'ai essayé:

J'ai ajouté le service dans @NgModuleproviders tableau dans appmodule.ts fichier afin qu'il soit disponible pour tous les composants du projet.

Code de service:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from '../../node_modules/rxjs';

@Injectable({
  providedIn: 'root'
})
export class SocialService {

  constructor() { }

  private valueObs: BehaviorSubject<string> = new BehaviorSubject<string>(null);

 public setValue(value: string):void {
     this.valueObs.next(value);
     this.getValue();
 }

 public getValue():Observable<string> {
     return this.valueObs;

 }

}

Composant B: Définition de la valeur ici

@Component({
  selector: 'app-componentb',
  templateUrl: './componentb.component.html',
  styleUrls: ['./componentb.component.scss']
})


constructor(private socialService: SocialService, private http: HttpClient) {



}

 buttonClick()
 {

    this.socialService.setValue("linked successfully");
 }

Composant A: Obtenez la valeur ici

@Component({
  selector: 'app-componenta',
  templateUrl: './componenta.component.html',
  styleUrls: ['./componenta.component.scss']
})


constructor(private socialService: SocialService, private http: HttpClient) {

       this.socialService.getValue().subscribe(data=>{

    console.log('Trigger from ComponentB');
    console.log(data);

});

}

Le déclencheur dans ComponentA est appelé lorsque ComponentA est chargé avec des données null. Mais il n'est pas appelé lorsque buttonClick est appelé à partir de ComponentB.

MISE À JOUR :

J'ai compris le problème, j'aurais dû formuler ma question correctement. Lorsque ComponentA et ComponentB sont dans la même page (URL), le code fonctionne parfaitement.

Comment envoyer des données entre 2 composants lorsqu'ils se trouvent sur 2 pages différentes (URL).

Exemple: L'utilisateur ouvre URL1 (Renders ComponentA) qui a un bouton, l'utilisateur clique sur le bouton et est redirigé vers URL2 (Renders ComponentB) dans un nouvel onglet qui a un bouton, lorsque l'utilisateur clique sur le bouton, je dois transmettre des données à ComponentA et fermez URL2. J'ai besoin de récupérer les données transmises dans ComponentB et de les utiliser dans URL1. Est-il possible d'utiliser les services? Sinon, quelle approche dois-je suivre?

7
Anirudh

Le problème est à votre service. Lorsque vous définissez les données, le sujet a déjà émis la valeur. Fait comme ça.

  1. Dans votre service, rendez BehaviorSubject public et vous n'avez plus besoin de la méthode getValue.

  2. Dans ComponetA où vous recevez les données de CompoenetB, abonnez-vous à BehaviorSubject qui est valueObs.

Classe de service modifiée comme suit.

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable()
export class SocialService {

  public valueObs: BehaviorSubject<string> = new BehaviorSubject<string>(null);

  constructor() {}

  public setValue(value: string):void {
     this.valueObs.next(value);
     // this.getValue();
  }

 // public getValue():Observable<string> {
 //     return this.valueObs;
 // }
}
0
Anuradha Mudalige

Si je ne me trompe pas, vous avez besoin de subsribe ou d'utiliser async pipe dans le modèle pour le composant a afin que vous obteniez toujours la dernière valeur du flux observable.

J'ai créé une application simple pour vous le démontrer.

Supposons que nous ayons 2 routes, dont chacune rend le composant pertinent (a, b).

Nous utilisons un service pour partager des données entre deux composants.

Injectable()
export class MyService {

  private _data = new BehaviorSubject<string>(null);

  setValue(value: string): void {
    this._data.next(value)
  }

  get data(): Observable<string> {
    return this._data;
  }

}

Ensuite, dans le composant a, nous écoutons les changements du flux observable du service.

@Component({
  selector: 'a-component',
  template: `Component A <br> Data: <pre>{{data}}</pre>`,
})
export class AComponent {
  @Input() name: string;

  data: Observable<string>;

  constructor(private myService: MyService) {
    this.myService.data.subscribe(data => this.data = data);
  }

Dans le composant b, nous éditons simplement les données via la méthode service setValue.

@Component({
  selector: 'b-component',
  template: `Component B <br> 
  <input type="text" placeholder="set data for component a" [(ngModel)]="modifiedData" (ngModelChange)="editServiceData($event)"/>`,
})
export class BComponent  {
  @Input() name: string;
  modifiedData;

  constructor(private myService: MyService) {}

  editServiceData(data: string) {
    this.myService.setValue(data)
  }
}

Voici l'extrait qui illustre le flux ci-dessus

0
Korte
getValue method should return observable.

public getValue():Observable<string> {
     return this.valueObs.asObservable();
}

Vous pouvez supprimer getValue () qui est appelée dans la méthode setValue ().

Composant:

this.socialService.getValue().subscribe(data=>{
    console.log('Trigger from ComponentB');
    console.log(data);
  });

StackBlitz: https://stackblitz.com/edit/angular-e6uxlo?file=src%2Fapp%2Fhello.component.ts

0
Suresh Kumar Ariya