繁体   English   中英

在整个 Angular 应用程序中共享 API 调用的结果

[英]Sharing the results of an API call throughout an Angular application

如何存储或缓存局部变量,以便 API 调用的结果可以在整个应用程序中共享?

我有以下 Angular 6 模块,它基本上创建了一个提及指令,以便能够执行在许多应用程序中流行的 @mentions:

@NgModule({
    imports: [
        CommonModule
    ],
    exports: [
        MentionDirective,
        MentionListComponent
    ],
    entryComponents: [
        MentionListComponent
    ],
    declarations: [
        MentionDirective,
        MentionListComponent
    ]
})
export class MentionModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: MentionModule
        };
    }
}

这是实际的指令:

export class MentionDirective implements OnInit, OnChanges {
items: any[];

constructor(
  public autocompletePhrasesService: AutocompletePhrasesService
) { }

  ngOnInit() {
    this.autocompletePhrasesService.getAll()
      .pipe(first())
      .subscribe(
        result => {
          this.items = result;
        },
        () => { });

该指令调用我的核心模块中的一个函数来检索数据:

export class AutocompletePhrasesService {

    public autoCompletePhrases: string[];

    constructor(private http: HttpClient) { }

    getAll(): Observable<string[]> {
        return this.http.get<string[]>(this.baseUrl + '/getall');
    }

我的问题是该指令在单个页面上可能有 20-30 个实例,并且该指令的每个实例都会调用 API。 如何更改我的代码,以便每个应用程序实例只调用一次 API?

API 中的数据不会经常更改。

我尝试将服务的结果存储在公共 autoCompletePhrases 变量中,并且仅在它为空时才调用它,但这没有用

你想要一些像“缓存”这样的东西。 它易于服务使一些人喜欢

data:any;
getData()
{
    if (!this.data)
      return this.httpClient.get(....).pipe(
        tap(result=>{
            this.data=result
        }))
    return of(this.data)
}

当您订阅“getData”时可能会发生两件事:this.data 有值,然后返回一个带有数据的 observable。 或者这个数据没有值,返回一个get,并将结果存入data -tap在subscribe之后执行-。 因此,您始终订阅“getData”,但该服务仅在没有数据时才调用 API(注意:可能发生多次调用并且多次​​调用 API)

下面是一些 AngularJS/TypeScript 代码来演示如何处理这个逻辑。 抱歉,但我没有时间将其转换为 Angular。 我确实相信还有一些软件包可以以更完整的方式处理缓存,但这是手动方法:)

private printerList: SelectItem[] = [];
private printerPromises: IDeferred<SelectItem[]>[] = [];
private printersLoading: boolean = false;
private printersLoaded: boolean = false;

public getPDFPrinterList(): ng.IPromise<SelectItem[]> {
  let defer: IDeferred<SelectItem[]> = this.$q.defer<SelectItem[]>();

  this.printerPromises.push(defer);

  if (this.printersLoading) {
      return defer.promise;
  }

  if (this.printersLoaded) {
      for (let i = 0; i < this.printerPromises.length; i++) {
          this.printerPromises[i].resolve(this.printerList);
      }
      this.printerPromises = [];
  } else {
      this.printersLoading = true;
      this.$http.get<SelectItem[]>(this.printerListUrl, { cache: false }).then((response: ng.IHttpResponse<SelectItem[]>) => {
          if (response.data) {
              this.printerList = response.data;
              for (let i = 0; i < this.printerPromises.length; i++) {
                  this.printerPromises[i].resolve(this.printerList);
              }
              this.printerPromises = [];
              this.printersLoaded = true;
          } else {
              console.log('Server Error Obtaining Printer List');
              for (let i = 0; i < this.printerPromises.length; i++) {
                  this.printerPromises[i].reject('Server Error');
              }
              this.printerPromises = [];
          }
          this.printersLoading = false;
      }, (response: ng.IHttpResponse<any>) => {
          if (response.data) {
             console.log(response.data.Message ? response.data.Message : response.data);
          }
          for (let i = 0; i < this.printerPromises.length; i++) {
              this.printerPromises[i].reject('Server Error');
          }
          this.printerPromises = [];
      });
  }

  return defer.promise;
}

暂无
暂无

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

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