我正在使用angular(v6)服务从后端获取数据并将其存储在变量中。我只想调用一次api,并在需要不同组件时随时提供数据。
问题是我正在从不同组件中调用服务中的getPlans()函数以获取数据,对于每次调用,我在浏览器的“网络”标签中看到一个api调用。
如何避免每次我调用getPlans()函数并提供一次调用api并将其存储到变量中的数据时调用?
<c:forEach items="${educat}" var="item" varStatus="state" >
<p><c:out value="${item.schoolname}"/></p>
</c:forEach>
答案 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}}。