我正在尝试将Ionic's Infinite Scroll与来自添加到ngrx商店的api的分页数据一起使用,但我不确定我是否完全理解如何使其工作。
我找到this SO answer寻求Observables的帮助,但是从商店获取数据有点不同。我不能订阅来自api的响应,因为它是由Effect处理的。
这是我的简化代码:
模板
<ion-content padding>
<ion-list>
<ion-item *ngFor="let item of (items | async).results">
<h2>{{ item.name }}</h2>
</ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="infiniteScrolling$.next($event)">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-content>
组件
export class InventoryPage {
items: Observable<Items>;
infiniteScrolling$: Subject<any> = new Subject();
constructor(
public store: Store<AppState>,
public itemsActions: ItemsActions
) {}
ngOnInit() {
this.items = this.store.select(appState => appState.items);
this.store.dispatch(createAction('FETCH_ITEMS'));
// What should this.infiniteScrolling$ do here since dispatching
// actions does not return an observable?
}
}
存储
const initialState = { results: [] };
export function itemsReducer(items: Items = initialState, action: Action): Items {
switch (action.type) {
case 'FETCH_ITEMS_SUCCESS':
return { results: [...items.results, ...action.payload.results] };
default:
return items;
}
}
我是否在正确的轨道上,如果是的话,一旦从api返回数据,我应该在哪里拨打infiniteScroll.complete()
?
答案 0 :(得分:1)
如果您使用的是NgRx,则应将加载微调器的状态(显示或隐藏)保存在商店中。对于Ionic的无限滚动实现,这有点棘手,因为微调器的可见性并不与变量相关,而您可以轻松地链接至状态。在其实现中,微调框会自动显示何时发出ionInfinite
,并且您必须在分派的事件上显式调用complete
才能再次隐藏它。
如果可以将输入传递给ion-infinite-scroll元素以显示或隐藏加载微调器,则将是理想的。然后,您可以在商店中保存一个loading
变量,以捕获请求的状态并将其传递给ion-infinite-scroll元素。发出ionInfinite时,只需调度一个动作即可获取下一页结果。在减速器中,请求动作应将loading
设置为true
(这样旋转器就会显示),效果中分派的成功动作应将其设置回false
(这样旋转器是隐藏的)再次)。
由于Ionic并非开箱即用,因此您可以添加一条指令来实现此行为:
import { Directive, HostListener, Input, OnChanges, SimpleChanges } from "@angular/core";
@Directive({
selector: '[appInfiniteScroll]'
})
export class InfiniteScrollDirective implements OnChanges {
@Input() loading: boolean;
private event: CustomEvent;
@HostListener('ionInfinite', ['$event'])
public onIonInfinite(event: CustomEvent) {
this.event = event;
}
public ngOnChanges(changes: SimpleChanges): void {
if (changes.loading && !this.loading && this.event) {
(this.event as any).complete();
this.event = null;
}
}
}
然后将其添加到ion-infinite-scroll元素中,并将加载状态变量传递给loading
输入:
<ion-infinite-scroll
appInfiniteScroll
[loading]="loading$ | async"
(ionInfinite)="fetchNextPage()">
<ion-infinite-scroll-content>
</ion-infinite-scroll-content>
</ion-infinite-scroll>
如果有帮助,我将示例放在StackBlitz中。
答案 1 :(得分:0)
我有这个:
<ion-infinite-scroll (ionInfinite)="doInfinite($event)">
doInfinite(event) {
this.store.dispatch({type: SET_FILTER, payload});
event.target.complete();
}