Угловой асинхронный перезарядный счетчик
У меня есть простая настройка, чтобы показать загрузчик, когда асинхронный канал пуст:
<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.