带有ngrx-store的离子无限滚动

问题描述 投票:2回答:1

[我正在尝试将Ionic's Infinite Scroll与来自添加到ngrx存储区的api的分页数据一起使用,但是我不确定我是否完全理解如何使其工作。

我找到this SO answer来获得Observable的帮助,但是从存储中获取数据有些不同。由于它是由效果处理的,因此我无法订阅api的响应。

这是我的简化代码:

模板

<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()

angular ionic2 ngrx
1个回答
0
投票

[如果您使用的是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;
    }

  }

}

然后将其添加到离子无限滚动元素中,并将加载状态变量传递到loading输入:

<ion-infinite-scroll 
  appInfiniteScroll
  [loading]="loading$ | async"
  (ionInfinite)="fetchNextPage()">
  <ion-infinite-scroll-content>
  </ion-infinite-scroll-content>
</ion-infinite-scroll>

如果有帮助,我将示例放在StackBlitz中。

© www.soinside.com 2019 - 2024. All rights reserved.