[英]Caching Data From HttpClient in Angular 4
我有一個問題,使我的緩存更簡單。 我認為有更好的方法來做到這一點。 我的問題是我必須在每個get()函數中執行此“緩存”代碼,這會導致代碼更長。 有誰幫助如何做到這一點最好的方式? 謝謝。 這是我的代碼如下。 我在我的代碼中做的是我在news.service.ts中執行get()函數以從http獲取數據,並在我的新聞列表中訂閱它。
news.service.ts
getAllNews() {
if(this.newslist != null) {
return Observable.of(this.newslist);
}
else {
return this.httpClient
.get('http://sample.com/news')
.map((response => response))
.do(newslist => this.newslist = newslist)
.catch(e => {
if (e.status === 401) {
return Observable.throw('Unauthorized');
}
});
}
}
新聞list.service.ts
this.subscription = this.newsService.getAllNews()
.subscribe(
(data:any) => {
console.log(data);
this.newslists = data.data.data;
},
error => {
this.authService.logout()
this.router.navigate(['signin']);
});
}
如果您打算使用通用的,可以用於不同的API調用或服務,那么您可以執行以下操作:
import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
class CacheItem<T> {
url: string;
timestampCached: number;
data: T;
}
@Injectable({
providedIn: 'root'
})
export class MyCachedHttpClient {
cache: CacheItem<any>[] = [];
constructor(
private http: HttpClient,
) { }
get<T>(url: string, cacheTime?: number, forceRefresh: boolean = false)
: Observable<T> {
let cachedItem: CacheItem<T> = this.getCachedItem<T>(url);
if (cachedItem != undefined && !forceRefresh) {
let expireDate = cachedItem.timestampCached + cacheTime;
if (Date.now() < expireDate) {
return of(cachedItem.data);
}
}
return this.http.get<T>(url).pipe(
map(data => {
if (cacheTime) { // if we actually want to cache the result
if (cachedItem == undefined) {
cachedItem = new CacheItem();
cachedItem.url = url;
this.cache.push(cachedItem);
}
cachedItem.data = data;
cachedItem.timestampCached = Date.now();
}
return data;
})
);
}
private getCachedItem<T>(url: string): CacheItem<T> {
return this.cache.find(item => item.url == url);
}
}
然后在任何地方使用MyCachedHttpClient
而不是HttpClient
。
筆記:
HttpClient
的get()
函數的許多功能,因為我沒有在這里重新實現options
參數。 我不太清楚news.service.ts
和news-list.service.ts
之間的區別是什么,但主要的概念是你需要分開關注點。 您可以做的最基本的分離是從“數據消費者”中分離“數據提供者”
這可以是獲取和管理數據的任何內容。 無論是內存緩存數據,服務調用等。在您的示例中,在我看來, news.service.ts
它是與新聞相關的所有內容的Web API客戶端/代理。
如果這是一個小文件,您可以將所有與新聞相關的緩存管理移動到此文件或...創建另一個管理緩存並包裝news.service.ts
。 該組件將從其緩存中提供數據,如果緩存不存在或已過期,則它將調用news.service.ts
方法。 這樣news.service.ts
唯一的責任就是向API發出ajax請求。
這是一個沒有承諾,可觀察或錯誤處理的例子,只是為了給你一個想法......
class NewsProvider{
constructor(){
this.newsCache = [];
}
getNewsItemById(id){
const item = this.newsCache.filter((i) => {i.id === id});
if(item.length === 1) return item[0];
this.newsCache = newsService.getAllNews();
item = this.newsCache.filter((i) => {i.id === id});
if(item.length === 1) return item[0];
else return null;
}
}
這些將是需要數據的任何組件,主頁中的新聞自動收錄器,導航菜單中某處的徽章通知......可能存在需要與新聞相關的數據的任何組件(或視圖)。 因此,這些組件/視圖不需要知道數據來自何處。
這些組件將使用“數據提供者”作為主要數據源
只需要(可以)在一個地方管理緩存以及與網絡相關的操作
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.