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 调用。