3

当异步管道为空时,我有一个简单的设置来显示加载微调器:

<div *ngIf="(searchResults$ | async) as searchResults; else loading">
</div>
<ng-template #loading>
    loading..
</ng-template>

但是,当用户再次搜索第二次时,加载.. 没有显示,我想我需要这个 searchResults$ observable 发出 null 以再次显示微调器,或者有一个单独的 isLoading 变量。

最好的方法是什么?

如果重要的话,我有一个 debounce 和一个 switchMap(即使用 finalize 等很棘手)

this.searchResults$ = this.filters$
      .pipe(
        debounceTime(200),
        distinctUntilChanged(),
        switchMap((f) => {
            return httpGet(f)
        })
      )

另外,我尝试过*ngIf="!isLoading && (searchResults$ | async) as searchResults但发现它有问题,例如 searchResults$ 未订阅,或者在更改检测后有角度抱怨更改

4

2 回答 2

3

您可以尝试使用 tap 运算符设置 isLoading 变量,如下所示:

this.searchResults$ = this.filters$
      .pipe(
        debounceTime(200),
        distinctUntilChanged(),
        tap(() => {this.isLoading = true}),
        switchMap((f) => {
            return httpGet(f)
        }),
        tap(() => {this.isLoading = false})
      );

然后,您可以通过将其托管在ng-container元素内的不同 *ngIf 中来绕过 angular 而不订阅您的 observable 。

<ng-container *ngIf="(searchResults$ | async) as searchResults">
  <div *ngIf="!isLoading"></div>
</ng-container>
<ng-template *ngIf="isLoading">
    loading..
</ng-template>
于 2019-02-17T22:59:53.557 回答
2

我遇到了同样的问题并解决了区分“询问”流和“结果”流的问题,将两者合并为可观察的组件结果。像这样的东西(基于您的代码):

this.searchResults$ = merge(
      this.filters$.pipe(map(f => null)),
      this.filters$.pipe(
        debounceTime(200),
        distinctUntilChanged(),
        switchMap((f) => {
            return httpGet(f)
        })
      )
    );
于 2019-02-17T21:59:04.627 回答