way - data binding angular 5



Mise en cache des résultats avec le service angular2 http (2)

J'expose une requête HTTP GET via un service et plusieurs composants utilisent ces données (détails du profil d'un utilisateur). Je voudrais que la première demande de composant exécute effectivement la demande HTTP GET sur le serveur et mette en cache les résultats afin que les demandes subséquentes utilisent les données mises en cache, au lieu d'appeler à nouveau le serveur.

Voici un exemple pour le service. Comment recommanderiez-vous l’implémentation de cette couche de cache avec Angular2 et typescript?

import {Inject, Injectable} from 'angular2/core';
import {Http, Headers} from "angular2/http";
import {JsonHeaders} from "./BaseHeaders";
import {ProfileDetails} from "../models/profileDetails";

@Injectable()
export class ProfileService{
    myProfileDetails: ProfileDetails = null;

    constructor(private http:Http) {

    }

    getUserProfile(userId:number) {
        return this.http.get('/users/' + userId + '/profile/', {
                headers: headers
            })
            .map(response =>  {
                if(response.status==400) {
                    return "FAILURE";
                } else if(response.status == 200) {
                    this.myProfileDetails = new ProfileDetails(response.json());
                    return this.myProfileDetails;
                }
            });
    }
}

Answer #1

En ce qui concerne votre dernier commentaire, voici la manière la plus simple à laquelle je puisse penser: créer un service qui aura une propriété et cette propriété contiendra la demande.

class Service {
  _data;
  get data() {
    return this._data;
  }
  set data(value) {
    this._data = value;
  }
}

Aussi simple que cela. Tout le reste dans la plnkr serait intacte. J'ai supprimé la requête du service car elle sera automatiquement instanciée (nous ne faisons pas de new Service... et je ne connais pas de moyen facile de passer un paramètre par le constructeur).

Donc, maintenant, nous avons le service, ce que nous faisons maintenant est de faire la demande dans notre composant et de l’affecter aux data variable de service data

class App {
  constructor(http: Http, svc: Service) {

    // Some dynamic id
    let someDynamicId = 2;

    // Use the dynamic id in the request
    svc.data = http.get('http://someUrl/someId/'+someDynamicId).share();

    // Subscribe to the result
    svc.data.subscribe((result) => {
      /* Do something with the result */
    });
  }
}

N'oubliez pas que notre instance de service est la même pour chaque composant. Ainsi, lorsque nous affectons une valeur à des data elle est reflétée dans chaque composant.

Voici le plnkr avec un exemple de travail.

Référence


Answer #2

J'ai omis la gestion de userId . Il faudrait pour cela gérer un tableau de data et un tableau d' observable (un pour chaque userId demandé).

import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/observable/of';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/map';
import {Data} from './data';

@Injectable()
export class DataService {
  private url:string = 'https://cors-test.appspot.com/test';

  private data: Data;
  private observable: Observable<any>;

  constructor(private http:Http) {}

  getData() {
    if(this.data) {
      // if `data` is available just return it as `Observable`
      return Observable.of(this.data); 
    } else if(this.observable) {
      // if `this.observable` is set then the request is in progress
      // return the `Observable` for the ongoing request
      return this.observable;
    } else {
      // example header (not necessary)
      let headers = new Headers();
      headers.append('Content-Type', 'application/json');
      // create the request, store the `Observable` for subsequent subscribers
      this.observable = this.http.get(this.url, {
        headers: headers
      })
      .map(response =>  {
        // when the cached data is available we don't need the `Observable` reference anymore
        this.observable = null;

        if(response.status == 400) {
          return "FAILURE";
        } else if(response.status == 200) {
          this.data = new Data(response.json());
          return this.data;
        }
        // make it shared so more than one subscriber can get the result
      })
      .share();
      return this.observable;
    }
  }
}

Exemple Plunker

Vous pouvez trouver une autre solution intéressante à l' https://.com/a/36296015/217408





typescript