在服务上存储持久性数据(Angular 2)

时间:2018-04-27 07:49:50

标签: angular typescript

首先,我想分享下一个信息:
我有两个服务,一个获取http请求,另一个存储数据。我尝试了很多方法,但我无法得到它。我想在第二个服务上存储数据,以从不同的组件获取数据,并且不要干(在每个组件上)。

具体问题:我从API获取http请求,然后我想存储json响应(存储在数组或对象上)以获取持久数据并获取每个组件的信息。我将分享我尝试的内容,但它在第二项服务(artist.service.ts)上没有用。

// spotify.service.ts

import { Injectable } from '@angular/core';

import { HttpClient, HttpHeaders } from '@angular/common/http';
import 'rxjs/add/operator/map';

@Injectable()
export class SpotifyService {


  urlSpotify: string = 'https://api.spotify.com/v1/';
  token: string = 'BQDejsMxhS-8621YfIhK_X6uxZcFY4LIBTNNxVIDAPimiBBU5t7lQlQCUboZkt5JBypYq-IH4dv9bhxQgaU';


  constructor(public http: HttpClient) {
        console.log('SpotyApp Ready');
   }

   private getHeaders(): HttpHeaders {
     let headers = new HttpHeaders({
        'authorization': `Bearer ${ this.token }`
      });

     return headers;
   } 



getArtista( id: string ) {
       let url = `${ this.urlSpotify }artists/${ id }`;

      let headers = this.getHeaders();

      return this.http.get(url, { headers});
   }

   // Methods
// artist.service.ts

import { Injectable } from '@angular/core';
import { SpotifyService } from './spotify.service';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';


@Injectable()
export class ArtistService {

artist: any = {};

constructor(private _spotify: SpotifyService, public route: ActivatedRoute) {}

 // It doesnt work....
 getArtista(id): Observable<any> {
    if (this.artist) {
        return Observable.of(this.artist);
    }
    return this._spotify.getArtista(id).do(artist => {
        console.log(artist, 'Artista');
        this.artist = artist;
    });
 }


  // It doesnt work...It works only on EVERY component.

getArtista(): void{
this.route.params.map(params => params['id'])
  .subscribe(id => {
    this._spotify.getArtista(id)
      .subscribe(artist => {
        console.log(artist, 'Artista');
            this.artist = artist;
      });
// artist.component.ts

import { Component, OnInit } from '@angular/core';
import { ArtistService } from '../../services/artist.service';

@Component({
  selector: 'app-artist',
  templateUrl: './artist.component.html'
})
export class ArtistComponent implements OnInit {

  artist: any = {};


  constructor(public _artist: ArtistService) {}

  ngOnInit() {
    this.artist = this._artist.getArtista();
  }
}

1 个答案:

答案 0 :(得分:0)

看起来您正在尝试在服务上缓存艺术家以避免重复调用,但缓存还应该有一个基于艺术家id的地图。此外,当您认为缓存与其他操作变脏时,缓存机制永远不会像看起来那么容易。如果网络呼叫不是那么昂贵,强烈建议不要缓存它。传统上存在最小化网络呼叫的趋势,但我个人并不认为某些KB对用户很重要。

此外,使用ActivatedRoute更适合相应的组件,并将服务限制在其目的之内。

持久性在这里没有任何意义。它存储在volatile变量中。持久性至少应该指本地存储。

// artist.service.ts

import { Injectable } from '@angular/core';
import { SpotifyService } from './spotify.service';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';


@Injectable()
export class ArtistService {
artistsSources = {};
artists = {};
constructor(private _spotify: SpotifyService) {}

 getArtista(id): Observable<any> {
    if(this.artists[id]) {
        return this.artists[id];
    } else {
        this.artistsSources[id] = new BehaviorSubject(null);
        this.artists[id] = this.artistsSources[id].asObservable().filter(Boolean);

        this._spotify.getArtista(id).do(artist => this.artistsSources[id].next(artist));
    }
    return this.artists[id];
 }
}
// artist.component.ts

import { Component, OnInit } from '@angular/core';
import { ArtistService } from '../../services/artist.service';

@Component({
  selector: 'app-artist',
  templateUrl: './artist.component.html'
})
export class ArtistComponent implements OnInit {

  artist: Observable<any>;


  constructor(public _artist: ArtistService, private route: ActivatedRoute) {
    this.artist = this.route.params.map(params => params['id'])
        .switchMap(id =>  this._artist.getArtista(id))
        // you can optionally subscribe here and set this.artist as normal object
        // this example uses async pipe in template instead
        // if you subscribe, make sure you unsusbscribe in onDestry
  }

  ngOnInit() {
  }
}
//artist.component.html

{{(artist | async)?.name}}