我有一个Angular应用,其中同时渲染了两个同级组件,它们需要相同的数据。 (一个是列出所有站点的导航栏,另一个是在我的路由器出口中的列出所有站点/图形的数据等)
为了减少一次要调用该服务的http请求,请将数据存储在全局变量中,然后从同级组件访问该数据。
但是,由于它们都是同时加载的,因此从一个组件调用的数据没有时间在另一组件尝试从服务接收数据之前将其放入服务中。
组件A (将数据存储在服务的全局变量“ all_sites”中)
ngOnInit() {
this.myService.getSites()
.subscribe(data => {
this.sites = data
this.myService.all_sites = data
})
}
组件B 出现未定义。
ngOnInit() {
console.log(this.myService.all_sites)
}
那么我是否有办法将数据发送到同级组件,并让它们同时使用数据? 就像我在父母那里做的一样:
<app-componentA></app-componentA>
<app-componentB></app-componentB>
其他复杂情况使得仅从父级调用(Authtoken2的东西)变得很困难。我的最终目标是减轻服务器上的负载
谢谢!!任何建议表示赞赏
答案 0 :(得分:0)
似乎您正在一个组件中使用组件A和组件B。因此,您可以在该父对象中进行http调用并使用ngIf吗?
requests.put(..., json=raw_data, ...)
希望有帮助!
答案 1 :(得分:0)
您正在IN组件ngOnInit()中进行操作,您可以在父组件ngOnInit()中执行该操作,并将this.sites作为输入传递给两个同级兄弟。
以这种方式,您可以实现您想要的。一旦加载了父级并称为服务
,请求和子级的请求就会更少答案 2 :(得分:0)
如果要实施此方案:
创建一个Subject
,它会在http响应到达时发出一个值。之后,这非常简单,您只需订阅此Observable
即可在其他组件中获取数据。
在父组件中发送http请求:
另一种简单的解决方案是将请求发送给父组件,然后使用Input
将值传递给子组件。
考虑使用redux :
Redux
是一个非常强大的工具。您可以将响应存储在状态中,Observers
在子组件中将通过选择器通知。
答案 3 :(得分:0)
您可以尝试
Object.assign(this.myService.all_sites, data)
代替
this.myService.all_sites = data
答案 4 :(得分:0)
发生该错误的原因是,两个组件调用ngOnInit
之前,在从componentA
进行的调用中可从服务返回的观察结果已解决。因此,在componentB
进行的呼叫中,字段all_sites
仍然是undefined
。
最简单的方法是缓存可观察对象,并使所有组件仍然访问该方法。只有服务应该知道/关心缓存。
export class MyService {
private getSitesObservable: Observable<Sites[]>;
getSites(): Observable<Sites[]> {
if(!this.getSitesObservable)
this.getSitesObservable = this.http.....;
return this.getSitesObservable;
}
}
然后在两个组件(或调用此服务方法的任何组件)中:
ngOnInit() {
this.myService.getSites().subscribe(data => {
this.sites = data;
});
}
答案 5 :(得分:0)
您可以将服务调用逻辑移到容纳两个组件的父组件中,并将数据作为输入传递:
所以结构如下
<app-component-parent>
<app-component-a></app-component-a>
<app-component-b></app-component-b>
<app-component-parent>
在app-component-parent.component.ts中,通过ngOnInit调用服务:
sites: SITES_TYPE;
ngOnInit() {
this.myService.getSites()
.subscribe(data => {
this.sites = data
})
}
然后在兄弟姐妹中,将“站点”作为输入传递:
<app-component-a [sites]="sites"></app-component-a>
<app-component-b [sites]="sites"></app-component-b>
在每个组件中,执行以下操作:
@Input()
sites: SITES_TYPE;