web-dev-qa-db-fra.com

Angular 5 Service partagé avec plusieurs données

Sur Internet, j'ai trouvé un exemple illustrant comment partager des données avec un service:

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

@Injectable()
export class DataService {

  private subject = new Subject<any>();

  sendData(phone: any) {
    this.subject.next(phone);
  }

  clearData() {
    this.subject.next();
  }

  getData(): Observable<any> {
    return this.subject.asObservable();
  }

}

Ensuite, nous nous abonnons aux changements

subscription: Subscription;

this.subscription = this.dataService.getData()
  .subscribe(data => {
     this.someData= data;
  });

Ok, ça marche bien. Mais si je veux partager plus d'un élément? Il semble déraisonnable de copier ce code pour chaque élément, en ne modifiant que le nom. Mais je ne trouve pas de solutions abstraites. Peut-être utiliser map avec les noms et les données elles-mêmes, mais je ne comprends pas comment souscrire aux modifications dans ce cas et à quoi devrait ressembler le service.

4
ch.45

Pour ce faire, vous pouvez placer toutes les valeurs pertinentes dans un objet wrapper et cet objet dans le sujet (comportement). Chaque abonné modifie le contenu de sa valeur personnelle d’intérêt et réécrit ensuite l’enveloppe complète.

par exemple.

Disons que vous mettez tous les modèles que vous définissez dans models.ts. Voici l'emballage.

export class MyWrapper {
   constructor(
      public value1?: string,
      public value2?: number,
      public value3?: boolean
   ){}
}

Ensuite, vous importez ce modèle de wrapper dans votre service et tous les abonnés

import { Injectable } from '@angular/core';
import {Subject} from 'rxjs/Subject';
import {Observable} from 'rxjs/Observable';
import { MyWrapper } from '../models/models';

@Injectable()
export class DataService {

  private subject = new Subject<MyWrapper>();

  sendData(wrapper: MyWrapper) {
    this.subject.next(wrapper);
  }

  clearData() {
    this.subject.next();
  }

  getData(): Observable<MyWrapper> {
    return this.subject.asObservable();
  }

}

Et vous pouvez manipuler la valeur dans l'un des abonnés, qu'il s'agisse d'un service, d'une directive ou d'un composant. Juste un exemple! Il existe de nombreuses façons différentes de manipuler l’emballage dans les deux sens.

import { MyWrapper } from '../models/models';

private localWrapper: MyWrapper;

constructor(
 private dataService: DataService
){}

ngOnInit(): void {
   this.dataService.getData().subscribe(wrapper => {
      this.localWrapper = wrapper;
   });
}

// The wrapper in your service gets replaced and all subscribers
// get a fresh version of all contained values. This way you
// could exchange hundreds of values with only one set of methods
// and a single (Behavior)Subject.
private saveValue1(value: string): void {
   localWrapper.value1 = value;

   this.dataService.sendData(localWrapper);
}
6
Lynx 242

je pense que la solution que vous recherchez est similaire à la bibliothèque Ngrx. Dans ce cas, vous voulez créer un objet avec différentes couches de données (téléphones, adresses, noms, etc.) et le jeter dans BehaviorSubject.Chaque abonné peut ensuite extraire les informations nécessaires en utilisant l'opérateur Pluck de rxjs.if si vous le souhaitez. pour modifier certaines couches de données, vous devez utiliser des modifications de données immuables en appliquant un opérateur d'étalement et en ne modifiant que la couche dont vous avez besoin, les autres couches restant intactes.

1
pavel_pleshko