[英]Using Angular2 HTTP Service with caching mecanism
我通過服務公開了一個HTTP GET請求,並且幾個組件正在使用此數據(國家/地區列表)。 我希望第一個組件請求實際對服務器執行HTTP GET請求並緩存結果,以便后續請求將使用緩存的數據,而不是再次調用服務器。
這是我的服務:
import {Injectable} from '@angular/core'
import {Subject} from 'rxjs/Subject';
import {Message, SelectItem} from 'primeng/primeng';
import {Http, Headers, RequestOptions} from '@angular/http';
import {environment} from '../../../environments/environment';
import {Country} from '../../domain/country';
import {Response} from "@angular/http";
import {Observable} from 'rxjs/Observable';
import {ReplaySubject} from "rxjs/Rx";
import "rxjs/add/observable/of";
@Injectable()
export class ListsService {
private _listOfCountries:SelectItem[]=[];
private countries:SelectItem[]=[];
private options = new RequestOptions({headers: new Headers({'Content-Type': 'application/json'})});
constructor(private http:Http) {
console.log("create ListsService");
}
/**
* Get all countries
*/
getListOfCountries():Observable<SelectItem[]> {
console.log('this._listOfCountries==');
console.log(this._listOfCountries);
let countries$ = this._listOfCountries.length > 0? Observable.of(this._listOfCountries): this.http
.get(`${environment.backend_url}api/countries`, this.options)
.map(this.mapCountries)
.catch(this.handleError);
return countries$;
}
private mapCountries(response:Response):SelectItem[] {
let countries:Country[] = response.json();
let selectItems:SelectItem[] = countries.map((c) => {
return {label: c.frLabel, value: c.id}
});
this._listOfCountries = selectItems.map(a => Object.assign({}, a));
console.log('this._listOfCountries==');
console.log(this._listOfCountries);
return selectItems;
}
private handleError(error:any) {
let errorMsg = error.message || `Error during retrieving data from the API`;
return Observable.throw(errorMsg);
}
}
我將服務注入以下組件:
constructor(
private listService:ListsService,
private router: Router,
public fb:FormBuilder) {
...
}
ngOnInit() {
this.listService.getListOfCountries().subscribe(countries => {
console.log(countries);
this.listOfCountries = countries;
});
}
我僅在根模塊app.module.ts上聲明服務,如下所示:
...
import {ListsService} from "./shared/services/lists.service";
@NgModule({
declarations: [
AppComponent,
IntroComponent,
],
imports: [
// @angular
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
RouterModule.forRoot(routes, {useHash: true}),
...
//app
AdministrationModule,
],
providers: [MessageService, ListsService],
bootstrap: [AppComponent]
})
export class AppModule { }
我期望該服務維護_listOfCountries
字段中的數據,但始終將其初始化為空數組,因此我沒有所需的行為。
任何人都可以指出我如何解決此問題,並提出解決此問題的最佳方法?
解決方案*:我修改了服務,如下所示:
@Injectable()
export class ListsService {
private countriesSubject: Subject<SelectItem[]>;
private countriesRequest: Observable<SelectItem[]>;
private options = new RequestOptions({headers: new Headers({'Content-Type': 'application/json'})});
constructor(private http:Http) {
console.log("create ListsService");
this.countriesSubject = new ReplaySubject<SelectItem[]>(1);
}
/**
* Get all countries
*/
getListOfCountries(refresh: boolean = false) {
if (refresh || !this.countriesRequest) {
this.countriesRequest = this.http
.get(`${environment.backend_url}api/countries`, this.options)
.map(this.mapCountries)
.catch(this.handleError);
this.countriesRequest.subscribe(
result => this.countriesSubject.next(result),
err => this.countriesSubject.error(err)
);
}
return this.countriesSubject.asObservable();
}
private mapCountries(response:Response):SelectItem[] {
console.log('mapCountries');
let countries:Country[] = response.json();
let selectItems:SelectItem[] = countries.map((c) => {
return {label: c.frLabel, value: c.id}
});
return selectItems;
}
}
在我的組件上:
ngOnInit() {
this.listService.getListOfCountries().take(1).subscribe(countries => {
this.listOfCountries = countries;
});
}
使用ListsService
組件可以預訂Observable
,然后維護自己的緩存。
@Component({...})
export class SomeComponent implements OnInit {
private countries:SelectItem[]=[];
constructor(private listsService: ListsService) {}
ngOnInit() {
this.listsService.getListOfCountries()
.subscribe((countries: SelectItem[]) => {
this.countries = countries;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.