Angular 从服务器加载数据时的角度组件数秒为空

Angular 从服务器加载数据时的角度组件数秒为空,angular,angular-httpclient,Angular,Angular Httpclient,我正在使用httpclient构建一个带有api调用的angular应用程序,我没有为httpclient使用任何包或插件 下面是我在service.ts中的示例代码 getAdminMateriDetail(slug: any) { return this._http.get(this.apiURL + 'admin/material/' + slug).pipe( tap(console.log), shareReplay(1), tap(()

我正在使用httpclient构建一个带有api调用的angular应用程序,我没有为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.currentMatri
在服务器响应之前为空(假设它在0.1秒到1秒之间)。因此,在HTML中,您必须处理“当
this.currentMatri
为空时该怎么办?”


要处理此问题,请在显示异步数据的位置添加
*ngIf=“CurrentMatri”
,并在
*ngIf=“!CurrentMatri”
时添加另一个标记(div或任何标记),以便显示加载程序或任何东西…

这是预期的行为,因为您正在执行异步调用:

this.userService.getAdminMateriDetail(this.slug).subscribe(
  (data:any) => {
    this.currentMateri = data.data;
  },
  error => {
    console.log(error);
  }
)
在这里,
this.currentMatri
在服务器响应之前为空(假设它在0.1秒到1秒之间)。因此,在HTML中,您必须处理“当
this.currentMatri
为空时该怎么办?”


若要处理此问题,请在显示异步数据的位置添加
*ngIf=“currentMatri”
,并在
*ngIf=“!currentMatri”
时添加其他标记(div或任何标记),以便显示加载程序或任何东西……

API调用总是需要时间的。所以你需要创建加载器或者类似的东西。在组件模板中,您可以使用
ngIfElse

<ng-container *ngIf="loadedData; else loader">
  page content
</ng-container>

<ng-template #loader>Loading...</loader>

在上面的示例中,两个订阅得到了相同的结果。没有
shareReplay()
每个订阅都会触发API调用。

API调用总是需要时间。所以你需要创建加载器或者类似的东西。在组件模板中,您可以使用
ngIfElse

<ng-container *ngIf="loadedData; else loader">
  page content
</ng-container>

<ng-template #loader>Loading...</loader>


在上面的示例中,两个订阅得到了相同的结果。没有
shareReplay()
每个订阅都会触发API调用。

我忘记了this.currentMatri是空的,谢谢。但是我可以避免页面空白吗?正如我所说,通过添加
*ngIf
我正在这样做,我在加载数据时添加了一些类似spinner的东西,但我只是希望有一种方法可以避免加载,只需给用户提供数据实例这是一个异步数据。你不可能马上得到它。在使用它之前,您必须等待服务器给出答案。你可以把它看作是给朋友的一封信。他得等邮递员来了才能拿到信,他不能马上拿到,即使他在信箱前面……我忘了这个。currentmatteri是空的,谢谢。但是我可以避免页面空白吗?正如我所说,通过添加
*ngIf
我正在这样做,我在加载数据时添加了一些类似spinner的东西,但我只是希望有一种方法可以避免加载,只需给用户提供数据实例这是一个异步数据。你不可能马上得到它。在使用它之前,您必须等待服务器给出答案。你可以把它看作是给朋友的一封信。他必须等待邮递员来,然后才能收到信,他无法立即收到信,即使他在信箱前面……所以当我进入第一页时,我进行了api调用,然后我导航到第二页,然后再次进入第一页,它再次进行api调用?因为我每次访问/打开该组件时都会订阅它?如何避免?我可以使用像localstorage这样的东西吗?你可以添加一些缓存,但老实说,这不是个好主意。有很多方法可以缓存http请求的休止状态(HttpInterceptors,缓存在服务中)。但通常情况下,这是不必要的。如果你决定添加缓存,你应该知道什么简单的
shareReplay
服务对你来说是不够的(因为你在url-
slug
中有动态部分)。我明白了,所以答案是我的应用是正常的,对吗?我一直认为我的应用程序很糟糕,因为这一点。感谢一个lotso,在用户加载数据之前,我会给用户一个加载器/微调器。当我转到第1页时,我进行了api调用,然后导航到第2页,然后再次转到第1页它再次进行了api调用?因为我每次访问/打开该组件时都会订阅它?如何避免?我可以使用像localstorage这样的东西吗?你可以添加一些缓存,但老实说,这不是个好主意。有很多方法可以缓存http请求的休止状态(HttpInterceptors,缓存在服务中)。但通常情况下,这是不必要的。如果你决定添加缓存,你应该知道什么简单的
shareReplay
服务对你来说是不够的(因为你在url-
slug
中有动态部分)。我明白了,所以答案是我的应用是正常的,对吗?我一直认为我的应用程序很糟糕,因为这一点。谢谢,所以在用户加载数据之前,我只给他们一个加载器/微调器