AngularFire2 Firestore无限滚动

时间:2019-05-29 00:01:30

标签: javascript arrays angular firebase angularfire2

我似乎在任何地方都找不到我所需要的示例,因此,我将尝试在此处进行询问。我已经找到了这个示例(https://angularfirebase.com/lessons/infinite-scroll-with-firebase-data-and-angular-animation/),但是它是用于Firebase而不是Firestore。它使我达到了90%左右,但是我仍然遇到问题。

我正在使用ngx-infinite-scroll,但是它会不断循环遍历相同的数据,并且永远不会到达数据库列表的末尾。

这是我的Angular组件TS:

import { Component, OnInit, OnDestroy } from "@angular/core";
import { AngularFirestore, DocumentChangeAction } from "angularfire2/firestore";
import { map } from "rxjs/operators";
import { Observable } from "rxjs";
import * as _ from "lodash";

@Component({
  selector: "app-feed",
  templateUrl: "./feed.component.html",
  styleUrls: ["./feed.component.scss"]
})
export class FeedComponent implements OnInit {
  // path
  path = "feedItems";

  // add
  feedItems = [];
  status = [];

  // edit
  editStatus: boolean = false;
  itemID = "";

  // infinite scroll
  batch: number = 3; // size of each query
  last: any = "";
  empty: boolean = false;
  loading: boolean = false;

  constructor(private db: AngularFirestore) {}

  ngOnInit() {
    // original read - put into fetchItemsPaginated() function below to include infinite scroll - remove .limit() if it's not needed
    // this.db
    //   .collection(this.path, q => q.orderBy("timestamp", "desc").limit(5))
    //   .snapshotChanges()
    //   .subscribe(serverItems => {
    //     this.feedItems = [];
    //     serverItems.forEach(a => {
    //       let item: any = a.payload.doc.data();
    //       item.id = a.payload.doc.id;
    //       this.feedItems.push(item);
    //     });
    //   });

    this.fetchItemsPaginated();
  } // ngOnInit

  fetchItemsPaginated() {
    this.last = Date.now();
    this.paginate(this.batch, this.last)
      .pipe(
        map(data => {
          if (!data.length) {
            this.empty = true;
      }
      let last = _.last(data);

      if (last) {
        this.last = last.payload.doc.data().id;

        data.map(q => {
          this.feedItems.push(q.payload.doc.data());
        });
      }
    })
  )
  .subscribe();
  } // fetchItemsPaginated

  paginate(limit: number, last: any): Observable<DocumentChangeAction<any>[]> {
    return this.db
      .collection(this.path, ref =>
        ref
          .where("date", "<", last)
          .orderBy("date", "desc")
          .limit(limit)
        )
        .snapshotChanges();
   } // paginate (read function)

  onScroll() {
    this.loading = true;
    setTimeout(() => {
      this.fetchItemsPaginated();
      this.loading = false;
    }, 1500);
  } // onScroll

  add() {
    this.db.collection(this.path).add({
      timestamp: new Date(),
      date: Date.now(),
      status: this.status
    });
    this.status = [];
    this.fetchItemsPaginated();
  } // add

  edit(item) {
    this.editStatus = true;
    this.status = item.status;
    this.itemID = item.id;
    // console.log(this.itemID);
    // console.log(item);
  } // edit

  update() {
    this.db.doc(`${this.path}/${this.itemID}`).update({
      timestamp: new Date(),
      date: Date.now(),
      status: this.status,
      id: this.itemID
    });
    this.status = [];
    this.itemID = "";
    this.editStatus = false;
  } // update

  updateTimeStamp(item) {
    this.db.doc(`${this.path}/${item.id}`).update({
      timestamp: new Date()
    });
  } // updateTimeStamp

  cancelUpdate() {
    this.editStatus = false;
    this.status = [];
    this.itemID = "";
  } // cancelUpdate

  delete(item) {
    this.db.doc(`${this.path}/${item.id}`).delete();
  } // delete
} // FeedComponent OnInit

我认为我需要以某种方式在显示的数据中找到最后一个对象(在fetchItemsPaginated()函数中)。当它碰到onScroll()函数时,它会以某种方式从最后一个对象中拾取并运行另一个查询,但我不确定如何实现。

这是我组件的HTML

<div class="container mb-5" *ngIf="feedItems.length > 0">
  <div class="row">
    <div class="col">
      <div *ngFor="let item of feedItems">
        <div class="card mb-4">
          <div class="card-body">
            <p>{{ item.status }}</p>
            <small>{{ item.timestamp.toDate() | date: "fullTime" }}</small>
          </div>
          <div class="card-footer">
            <button class="btn btn-info mr-1" (click)="edit(item)">
              Edit
            </button>
            <button
              class="btn btn-success mr-1"
              (click)="updateTimeStamp(item)"
            >
              Update TimeStamp
            </button>
            <button class="btn btn-danger" (click)="delete(item)">
              Delete
            </button>
          </div>
        </div>
      </div>

      <!-- load more posts - infinite scroll - testing -->

      <div *ngIf="feedItems.length > 0 && !empty">
        <div
          *ngIf="loading"
          class="alert alert-warning d-block text-center position-absolute"
        >
          Loading more items...
        </div>
        <div
          class="search-results"
          infiniteScroll
          [infiniteScrollDistance]="2"
          [infiniteScrollThrottle]="50"
          (scrolled)="onScroll()"
        ></div>
      </div>

      <div *ngIf="empty" class="alert alert-primary d-block text-center">
        End of items in database... That's all folks!
      </div>
    </div>
  </div>
</div>

为了实现这一点,我认为我需要对来自最后一个数据对象的数据进行_.split,然后再显示_.concat。任何帮助都会很棒。

0 个答案:

没有答案