Угловой асинхронный перезарядный счетчик

У меня есть простая настройка, чтобы показать загрузчик, когда асинхронный канал пуст:

<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 $ не подписан, или подал жалобу на изменения после обнаружения изменений

3 ответа

Решение

Я столкнулся с той же проблемой и решил разграничить поток "спрос" и поток "результат", объединив оба компонента для наблюдаемого результата компонента. Примерно так (на основе вашего кода):

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

Вы можете попробовать установить переменную isLoading с помощью оператора tap следующим образом:

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

После этого вы можете обойтись без подписки на свой объект наблюдения, разместив его в другом *ngIf внутри элемента ng-container.

<ng-container *ngIf="(searchResults$ | async) as searchResults">
  <div *ngIf="!isLoading"></div>
</ng-container>
<ng-template *ngIf="isLoading">
    loading..
</ng-template>

Теперь я использую библиотеку ngx-http-request-state, которая дает состояния загрузки, ошибки и рендеринга. Он также может работать при перезагрузке, если вы используете scan() или withLatestFrom(). Также он работает с внутренними наблюдаемыми.

При использовании graphql я рассматриваю возможность использования комбинации параметров fetchPolicy, load и networkStatus.

Другие вопросы по тегам