如何在角度服务中存储从api接收的数据并避免多次api调用?

时间:2019-05-09 22:55:20

标签: angular angular-services

我正在使用angular(v6)服务从后端获取数据并将其存储在变量中。我只想调用一次api,并在需要不同组件时随时提供数据。

问题是我正在从不同组件中调用服务中的getPlans()函数以获取数据,对于每次调用,我在浏览器的“网络”标签中看到一个api调用。

如何避免每次我调用getPlans()函数并提供一次调用api并将其存储到变量中的数据时调用?

<c:forEach items="${educat}" var="item" varStatus="state" >
              <p><c:out value="${item.schoolname}"/></p>
 </c:forEach>

2 个答案:

答案 0 :(得分:0)

您可以使用 ReplaySubject BehaviorSubject 来实现该功能,如果您使用ReplaySubject,则必须指定要存储多少个旧值,以便订阅者以后可以访问, BehaviorSubject只能保留最后一个值

 import { ReplaySubject } from 'rxjs';

 ....
 @Injectable()
 export class SharedService {
 plans$: Observable<Plan[]> = this.plansSubject.asObservable(); 
 private plansSubject = new ReplaySubject<Plan[]>(1);

 constructor(private http: HttpClient) { }
 getPlans(){
   this.http.get().subscribe(res => this.plansSubject.next(res.plans)); // get array of plans
 }
}

,您可以像这样在组件中获取数据:

constructor(private sharedService: SharedService) { }

ngOnInit() {
 this.sharedService.getPlans(); // to get called only the first time to get data
 this.service.plans$.subscribe(...); // you have your data here without anu additional http call 
}

如果要刷新数据,可以调用方法

this.sharedService.getPlans();

对于 BehaviorSubject ,这是完全一样的东西,这里会有所变化

plans$: Observable<Plan[]> = this.plansSubject.asObservable(); 
private plansSubject = new BehaviorSubject<Plan[]>;

您可以在组件内部订阅以获取数据,也可以使用 BehaviorSubject.value

进行访问
constructor(private sharedService: SharedService) { }

ngOnInit() {
 this.service.plans$.subscribe((plans) => console.log(plans));
 // or access the value directly
 console.log(this.service.plans$.value)    
}

答案 1 :(得分:0)

这可以通过RxJs的shareReplay()完成。根据{{​​3}}

  

shareReplay返回一个可观察的源,该源是通过其多播的   一个ReplaySubject。该重播主题会因错误从   源,但不是源完成时。这使得shareReplay   非常适合处理诸如缓存AJAX结果之类的事情   可重试。这是重复的行为,但是与共享不同   它不会重复可观察到的源,而是会重复   源可观察值。

这使shareReplay()的用户非常适合您的用例。

请记住也要在您的服务上导入shareReplay()。

import { shareReplay } from 'rxjs/operators';
.
.

export class PlansService {
  private plansData: Observable<any>;

  constructor(private httpCallService: HttpCallService, private http: HttpClient) { 

    this.plansData = this.httpCallService.getHttpResponse("GET_PLANS")
      .pipe(
        shareReplay()
      );

  }

  getPlans(): Observable<any>{
    return this.plansData;
   }

}

然后,您可以在需要它的componenet上返回该可观察对象,并且如果您查看Inspect Element工具上的网络请求选项卡,则不会触发其他HTTP请求,因为每次{{{ 1}}。