Храните постоянные данные на Сервисах (Angular 2) - PullRequest
0 голосов
/ 27 апреля 2018

Прежде всего, я хотел бы поделиться следующей информацией:
У меня есть две службы, одна из которых получает запрос http, а другая - данные. Я пробовал много способов, но я не могу получить это. Я хочу хранить данные на втором сервисе, чтобы получать данные от разных компонентов и не СУХОЙ (на каждом компоненте).

Конкретная проблема: Я получаю http-запрос от API, затем я хочу сохранить ответ 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 голосов
/ 27 апреля 2018

Похоже, вы пытаетесь кэшировать художников в сервисе, чтобы избежать повторных вызовов, но в кэше также должна быть карта, основанная на id художника. Кроме того, механизм кэширования никогда не бывает таким простым, как кажется, когда вы думаете о загрязнении кэша другими операциями. Настоятельно рекомендуется не кэшировать его, если сетевые вызовы не такие дорогие. Традиционно наблюдается тенденция к минимизации сетевых вызовов, но я лично не думаю, что некоторые КБ будут иметь значение для Пользователя.

Кроме того, использование ActivatedRoute лучше подходит в соответствующем компоненте и ограничивает обслуживание только его назначением.

Также настойчивость здесь не имеет смысла. Хранение в энергозависимых переменных. Стойкость должна как минимум относиться к локальному хранилищу.

// 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}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...