首先,我想分享下一个信息:
我有两个服务,一个获取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();
}
}
答案 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}}