angular - 带 ngrx-store 的 Ionic 无限滚动

标签 angular ionic2 ngrx

我正在尝试使用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()

最佳答案

如果您使用 NgRx,加载微调器的状态(无论是显示还是隐藏)应保存在您的商店中。这对于 Ionic 的无限滚动实现来说有点棘手,因为旋转器的可见性并不与变量绑定(bind),而是可以轻松链接到状态。在其实现中,微调器会在发出 ionInfinite 时自动显示,并且您必须在分派(dispatch)的事件上显式调用 complete 才能再次隐藏它。

如果您可以将输入传递给 ion-infinite-scroll 元素来显示或隐藏加载微调器,那就太理想了。然后,您可以在商店中保存一个 loading 变量来捕获请求的状态,并将其传递给 ion-infinite-scroll 元素。发出 ionInfinite 时,只需调度一个操作即可获取下一页结果。在您的 reducer 中,请求操作应将 loading 设置为 true (以便旋转器显示),并且在效果中分派(dispatch)的成功操作应将其设置回 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 中整理了一个示例如果有帮助的话。

关于angular - 带 ngrx-store 的 Ionic 无限滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45136216/

相关文章:

javascript - 在 Angular2 中使用 Protractor

Angular Material 表页脚总计

angular - 从 ModalController.create() 将数据传递到组件

php - 如何从组件发送和获取数据到php? ionic 2

javascript - Ionic 2 上的翻转时钟

angular - 如何从 ngrx 商店中获取值(value)到我的模板中?

javascript - 使用路由之间共享的数据填充 ngrx 存储

angular - 我可以使用指定的种子运行 Karma 测试吗?

css - ionic 2 上的大小按钮与 col

angular - 将 ngrx 与 Angular 一起使用