简体   繁体   English

在 angular 服务中缓存数据

[英]caching the data in the angular service

I am have written an agreements service and need to fetch the data once it is retrieved.我已经编写了一个协议服务,并且需要在检索数据后获取数据。 The next time it should check the data if it exists and return the value from that variable.下次它应该检查数据是否存在并从该变量返回值。 I have declared a variable called private data: AgreementsModel[];我已经声明了一个名为私有数据的变量:AgreementsModel[]; How do I do that check in my service method我该如何检查我的服务方法

@Injectable()
export class AgreementsService {
  private baseUrl: string;
  private data: AgreementsModel[];

  constructor(private http: HttpClient, private appService: AppConfigService, public store: Store) {
    this.baseUrl = this.appService.getAppSettings().apiServer.agreements;
  }


  public getOutstandingAgreements(userAgreementId?: number): Observable<AgreementsModel[]> {
    let params = new HttpParams();
    if (userAgreementId) {
      params = params.set('userAgreementId', userAgreementId.toString());
  }

   return this.http.get<AgreementsModel[]>(`${this.baseUrl}outstanding-agreements`, {params});
  }

}

I have tried to do the following but getting compile error at line return this.data.我尝试执行以下操作,但在 return this.data 行出现编译错误。 The type AgreementModel[] is missing the following properties from type Promise. AgreementModel[] 类型缺少 Promise 类型的以下属性。

 public  getOutstandingAgreements(userAgreementId?: number): Promise<any> {
    let params = new HttpParams();
    if (userAgreementId) {
      params = params.set('userAgreementId', userAgreementId.toString());
    }

   if (this.data) {
    return this.data;
  }
    const result =  this.http.get<AgreementsModel[]>(`${this.baseUrl}outstanding-agreements`, {params})
                                                                   .pipe(map((x) => {this.data = x; })).toPromise();
    return result;
  }

If you want to cache it independent of the browser-session, the best solution is to use the IndexDB of the browser.如果要独立于浏览器会话缓存它,最好的解决方案是使用浏览器的 IndexDB。 I have created an indexDB-Service for managing it, but this one needs some improvements for upgrading if you want to use it in production.我已经创建了一个 indexDB-Service 来管理它,但是如果你想在生产中使用它,这个需要一些改进来升级。

export class IdbService {
  static STORES = {
    AGREEMENTS: 'agreements'
  };

  async getDb() {
    return await openDB('my-db', 1, {
      upgrade(db) {
        for (const key in IdbService.STORES) {
          const storeName = IdbService.STORES[key];
          if (!db.objectStoreNames.contains(storeName)) {
            db.createObjectStore(storeName);
          }
        }
      }
    });
  }
}

I have changed the service to work with promises.我已更改服务以使用承诺。 Of course you can change it a little bit to work with observables.当然,你可以稍微改变它来使用 observables。

export class AgreementsService {
  private baseUrl: string;
  private data: AgreementsModel[];

  constructor(
    private idbService: IdbService,
    private http: HttpClient, 
    private appService: AppConfigService, 
    public store: Store
  ) {
    this.baseUrl = this.appService.getAppSettings().apiServer.agreements;
  }


  public async getOutstandingAgreements(userAgreementId?: number): Observable<AgreementsModel[]> {
    let params = new HttpParams();
    if (userAgreementId) {
      params = params.set('userAgreementId', userAgreementId.toString());
    }

    const key = `outstanding-agreements__${userAgreementId.toString()}`;
    const db = await this.idbService.getDb();

    let result = await db.get(IdbService.STORES.AGREEMENTS, key);
    if (result ?.length) {
      return result ;
    }

    const result = await this.http.get<AgreementsModel[]>(`${this.baseUrl}outstanding-agreements`, {params}).toPromise();

    await db.put(IdbService.STORES.AGREEMENTS, result, key);
    return result;
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM