我有一个大项目,在这里我对API进行了一些HTTP GET调用,以获取不同的数据。我想将它们组合在一个调用中(我已经创建了它,并且我已将json与所有数据嵌套在一起),问题是我无法在组件之间传递数据。让我解释一下这个问题。这是电话:
get(entityType: string): Promise<any> {
return this.http
.get<any>(
this.location.prepareExternalUrl("./assets/temp-data/LEV_page/organisation.json")
)
.take(1)
.toPromise();
}
在我的主要组件中,我这样做:
public entityType:string;
public dataSource;
constructor(private levsService: LinkedEntityVocabulariesService) {}
ngOnInit() {
this.entityType = localStorage.getItem("currentEntityType");
this.levsService.get(this.entityType).then(data => {
this.dataSource = data;
});
}
如果我想在该组件中使用dataSource
,它可以正常工作,但是当我尝试将其传递给子组件时,如下所示:
<app-properties [send]="dataSource"></app-properties>
然后在那里访问它:
@Input("send") send;
constructor() {}
ngOnInit() {
console.log("test", this.send);
}
我得到的只是test undefined
,因为它在接收数据之前就通过了它(即使我认为使用Promise
而不是Observable
也会阻止它)。
无论如何,我的问题是: 我可以调用获取数据,然后在组件之间传递数据,而不是再次调用api吗?如果是,我该如何使用上面的示例? 预先感谢!
答案 0 :(得分:3)
无论您使用承诺食谱还是可观察食谱,尝试在可用数据之前访问数据都会产生 undefined 。例如,您可以仅在有数据时有条件地创建子组件
<app-properties [send]="dataSource" *ngIf="dataSource"></app-properties>
或者您可以在app-properties
组件内部检查dataSource
是否已定义,然后再尝试对其进行任何操作,正确的位置将是ngOnChanges
生命周期方法。
ngOnChanges() {
if (this.send) {
console.log(this.send);
}
}
答案 1 :(得分:1)
使组件不显示新数据的原因是Angular change detection.
它没有被触发,幸运的是在异步管道中内置了angular,它可以为您执行此操作。同样,此管道取消了事件订阅,因此角度覆盖了您的整个旅程。
使用这种方法:
public entityType:string;
public dataSource$: Observable<yourInterface>;
constructor(private levsService: LinkedEntityVocabulariesService) {}
ngOnInit() {
this.entityType = localStorage.getItem("currentEntityType");
this.datasource$ = this.levsService.get(this.entityType);
}
然后在您的html中使用此方法:
<app-properties [send]="dataSource$ | async"></app-properties>
然后您将异步加载数据。
异步管道订阅Observable或Promise,并返回其发出的最新值。发出新值时,异步管道会将要检查的组件标记为更改。当组件被销毁时,异步管道将自动退订,以避免潜在的内存泄漏。
如果您想了解更多信息,请看看here
答案 2 :(得分:0)
我也遇到过同样的情况,我们有一个API调用,它返回用户个人资料详细信息,并且应用程序中最大的组件都需要个人资料详细信息。
在Angular中,我们可以通过在服务(共享服务)中创建可共享对象来减少此API调用。我认为您可以在此处实施行为主题。对象需要在服务内部启动时进行初始化或声明,并且需要通过在组件中调用服务来在所有应用程序中调用该共享对象。为此,您需要从“ rxjs”导入库
private profileDataSource = new BehaviorSubject('');
profileData = this.profileDataSource.asObservable();
上面已将“ profileDataSource”声明为Behavior主题,值为“”。登录后,我在第一个组件中调用了此方法,并使用配置文件详细信息对其进行了初始化。在我们的案例中,如果用户更新配置文件详细信息,我们也会更新此对象,此更新将反映在我们更新BehavourSubject对象时。您可以在组件中调用此对象并使用共享数据。
深入学习主题