通过输入属性检索传递给子组件的值
Retrieve value passed to child component via input attribute
我有一个大项目,我在其中对 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 吗?如果是的话,我怎么能用上面的例子来做呢?
提前致谢!
无论您是使用 promise 配方还是 observable 配方,在数据可用之前尝试访问数据都会产生 undefined。例如,您可以仅在拥有数据时有条件地创建子组件
<app-properties [send]="dataSource" *ngIf="dataSource"></app-properties>
或者您可以在 app-properties
组件内部检查 dataSource
是否已定义,然后再尝试对其进行任何操作,正确的位置是 ngOnChanges
生命周期方法。
ngOnChanges() {
if (this.send) {
console.log(this.send);
}
}
导致您的组件不显示新数据的原因是 Angular change detection.
它没有被触发,幸运的是 angular 内置了异步管道,它可以为您完成。此外,此管道取消订阅事件,因此 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 和 returns 它发出的最新值。当发出新值时,异步管道标记要检查更改的组件。当组件被销毁时,异步管道会自动取消订阅以避免潜在的内存泄漏。
如果你想了解更多,请看一看here
我也遇到过同样的情况,我们有一个 API 调用 returns 用户配置文件详细信息,并且应用程序中的最大组件都需要该配置文件详细信息。
在Angular中,我们可以通过在服务(共享服务)中创建一个可共享对象来减少这个API调用。我想在这里你可以实现行为主题。一个对象需要在服务开始时初始化或声明,并且需要通过调用组件中的服务来跨所有应用程序调用该共享对象。为此,您需要从 'rxjs'
导入库
private profileDataSource = new BehaviorSubject('');
profileData = this.profileDataSource.asObservable();
以上声明 "profileDataSource" 为具有“ ”值的 BehaviorSubject。我在登录后的第一个组件中调用了它,并使用配置文件详细信息对其进行了初始化。在我们的例子中,如果用户更新配置文件详细信息,我们也会更新此对象,此更新将在我们更新 BehavourSubject 对象时反映出来。您可以在组件中调用此对象并使用共享数据。
在此处深入学习 Subjects https://rxjs-dev.firebaseapp.com/guide/subject
我有一个大项目,我在其中对 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 吗?如果是的话,我怎么能用上面的例子来做呢? 提前致谢!
无论您是使用 promise 配方还是 observable 配方,在数据可用之前尝试访问数据都会产生 undefined。例如,您可以仅在拥有数据时有条件地创建子组件
<app-properties [send]="dataSource" *ngIf="dataSource"></app-properties>
或者您可以在 app-properties
组件内部检查 dataSource
是否已定义,然后再尝试对其进行任何操作,正确的位置是 ngOnChanges
生命周期方法。
ngOnChanges() {
if (this.send) {
console.log(this.send);
}
}
导致您的组件不显示新数据的原因是 Angular change detection.
它没有被触发,幸运的是 angular 内置了异步管道,它可以为您完成。此外,此管道取消订阅事件,因此 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 和 returns 它发出的最新值。当发出新值时,异步管道标记要检查更改的组件。当组件被销毁时,异步管道会自动取消订阅以避免潜在的内存泄漏。
如果你想了解更多,请看一看here
我也遇到过同样的情况,我们有一个 API 调用 returns 用户配置文件详细信息,并且应用程序中的最大组件都需要该配置文件详细信息。
在Angular中,我们可以通过在服务(共享服务)中创建一个可共享对象来减少这个API调用。我想在这里你可以实现行为主题。一个对象需要在服务开始时初始化或声明,并且需要通过调用组件中的服务来跨所有应用程序调用该共享对象。为此,您需要从 'rxjs'
导入库 private profileDataSource = new BehaviorSubject('');
profileData = this.profileDataSource.asObservable();
以上声明 "profileDataSource" 为具有“ ”值的 BehaviorSubject。我在登录后的第一个组件中调用了它,并使用配置文件详细信息对其进行了初始化。在我们的例子中,如果用户更新配置文件详细信息,我们也会更新此对象,此更新将在我们更新 BehavourSubject 对象时反映出来。您可以在组件中调用此对象并使用共享数据。
在此处深入学习 Subjects https://rxjs-dev.firebaseapp.com/guide/subject