Angular 当来自服务器的加载数据为空白几秒钟时的组件
Angular component when load data from server is blank for a couple seconds
我正在使用 httpclient 构建 angular 个带有 api 调用的应用程序,我没有为那个 httpclient 使用任何包或插件。
这是我在 service.ts
中的示例代码
getAdminMateriDetail(slug: any) {
return this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
tap(console.log),
shareReplay(1),
tap(() => console.log('Materi Detail after sharing'))
)
}
我尝试从服务器获取材料细节,并在我的组件中
getCurrentMateriDetail() {
return this.userService.getAdminMateriDetail(this.slug).subscribe(
(data:any) => {
this.currentMateri = data.data;
},
error => {
console.log(error);
}
)
}
ngOnInit() {
this.getCurrentMateriDetail();
}
我在每个需要来自服务器的数据的页面中使用该代码,但我得到的是意想不到的结果,所以当我导航到调用 api 的组件并订阅该 api 时,我的组件有几秒钟是空白的,有时它很快。我刚开始使用 api 电话,这正常吗?或者也许我可以改进它以使其更快,这样用户就不会看到“空白页”?
我还阅读了有关缓存的内容,我发现 shareReplay(1)
所以我将它添加到我的代码中,但仍然有几秒钟空白。有人可以告诉我原因吗?
这是预期的行为,因为您正在进行异步调用:
this.userService.getAdminMateriDetail(this.slug).subscribe(
(data:any) => {
this.currentMateri = data.data;
},
error => {
console.log(error);
}
)
这里,this.currentMateri
在服务器响应之前为空(假设在0.1秒到1秒之间)。因此,在您的 HTML 中,您必须处理“当 this.currentMateri
为 null 时该怎么办?”
为了处理这个问题,在显示异步数据的地方添加 *ngIf="currentMateri"
,并在 *ngIf="!currentMateri"
时添加另一个标签(div,或其他),这样你就会显示一个加载器,或任何...
API 调用总是需要时间。所以你需要创建加载器或类似的东西。在组件模板中,您可以使用 ngIfElse
:
<ng-container *ngIf="loadedData; else loader">
page content
</ng-container>
<ng-template #loader>Loading...</loader>
shareReplay
用于订阅者之间可观察到的“冷”(more info) 共享结果。但在你的情况下它是无用的,因为你的函数的每次调用都会创建新的 Observable。示例:
// Correct usage:
const myMagicData$ = this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
tap(console.log),
shareReplay(1),
tap(() => console.log('Materi Detail after sharing'))
);
myMagicData$.subscribe();
myMagicData$.subscribe();
在上面的例子中,两个订阅都得到了相同的结果。如果没有 shareReplay()
,每个订阅都会触发 API 调用。
我正在使用 httpclient 构建 angular 个带有 api 调用的应用程序,我没有为那个 httpclient 使用任何包或插件。
这是我在 service.ts
中的示例代码 getAdminMateriDetail(slug: any) {
return this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
tap(console.log),
shareReplay(1),
tap(() => console.log('Materi Detail after sharing'))
)
}
我尝试从服务器获取材料细节,并在我的组件中
getCurrentMateriDetail() {
return this.userService.getAdminMateriDetail(this.slug).subscribe(
(data:any) => {
this.currentMateri = data.data;
},
error => {
console.log(error);
}
)
}
ngOnInit() {
this.getCurrentMateriDetail();
}
我在每个需要来自服务器的数据的页面中使用该代码,但我得到的是意想不到的结果,所以当我导航到调用 api 的组件并订阅该 api 时,我的组件有几秒钟是空白的,有时它很快。我刚开始使用 api 电话,这正常吗?或者也许我可以改进它以使其更快,这样用户就不会看到“空白页”?
我还阅读了有关缓存的内容,我发现 shareReplay(1)
所以我将它添加到我的代码中,但仍然有几秒钟空白。有人可以告诉我原因吗?
这是预期的行为,因为您正在进行异步调用:
this.userService.getAdminMateriDetail(this.slug).subscribe(
(data:any) => {
this.currentMateri = data.data;
},
error => {
console.log(error);
}
)
这里,this.currentMateri
在服务器响应之前为空(假设在0.1秒到1秒之间)。因此,在您的 HTML 中,您必须处理“当 this.currentMateri
为 null 时该怎么办?”
为了处理这个问题,在显示异步数据的地方添加 *ngIf="currentMateri"
,并在 *ngIf="!currentMateri"
时添加另一个标签(div,或其他),这样你就会显示一个加载器,或任何...
API 调用总是需要时间。所以你需要创建加载器或类似的东西。在组件模板中,您可以使用 ngIfElse
:
<ng-container *ngIf="loadedData; else loader">
page content
</ng-container>
<ng-template #loader>Loading...</loader>
shareReplay
用于订阅者之间可观察到的“冷”(more info) 共享结果。但在你的情况下它是无用的,因为你的函数的每次调用都会创建新的 Observable。示例:
// Correct usage:
const myMagicData$ = this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
tap(console.log),
shareReplay(1),
tap(() => console.log('Materi Detail after sharing'))
);
myMagicData$.subscribe();
myMagicData$.subscribe();
在上面的例子中,两个订阅都得到了相同的结果。如果没有 shareReplay()
,每个订阅都会触发 API 调用。