带有Anglefire Firestore的Ionic 3无限卷轴(加载更多物品)

时间:2018-07-15 00:45:02

标签: javascript angular ionic3 google-cloud-firestore angularfire2

我的离子应用程序中有此代码

home.ts:

    import { AlertsActionsProvider } from '../../providers/alerts-actions/alerts-actions';
    import { FirestoreProvider } from '../../providers/firestore/firestore';
    import { AuthProvider } from '../../providers/auth/auth';


    import { AngularFirestoreCollection } from 'angularfire2/firestore';
    import { AngularFirestoreDocument } from 'angularfire2/firestore';
    import { Observable } from 'rxjs/Observable';
    import * as moment from 'moment';

interface Post {
    id: Number,
    type: String,// text &&|| images || video || sound
    text: String,  
    images: String[],
    video: String,
    sound: String,
    created_by: any,
    created_at: any, // 2018-06-05T01:19:02Z
    updated_at: String, //2018-06-05T01:19:02Z
    likes_count: Number, // modified by cloud functions
    country: String,
    status: Number,// 0=> delete by admin | 1=> active

    //for slides 
    slidesPerView: Number,
    slidesPager: Boolean

}

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  postsCollectionRef: AngularFirestoreCollection<Post>;

  public user: Observable<any>;
  userDocumentRef: AngularFirestoreDocument<any>;

  timelineData: any = [];
  country = null;
  limit = 5;
  startAfter: any = null;


  constructor(
        public navCtrl: NavController,
        public app: App,
        public _ALERTS: AlertsActionsProvider,
        public authData: AuthProvider,
        private _DB: FirestoreProvider  
  ) {}


  //ionViewDidLoad -> only runs when entering the first time
  ionViewDidLoad() {
    this.getUserData();

    this.postsCollectionRef = this._DB.get_all_posts(this.country, this.limit, null);

    this.postsCollectionRef.valueChanges().subscribe((items) => {
      for (var i = 0, len = items.length; i < len; i++) {
        let postDoc = items[i];

        //for slides view
        postDoc.slidesPerView = 1;
        postDoc.slidesPager = false;
        if (postDoc.images && postDoc.images.length && !postDoc.video){
            if(postDoc.images.length > 1){
                postDoc.slidesPerView = 1.1;
                postDoc.slidesPager = true;
            }
        }

        if(postDoc.created_at)
            postDoc.created_at = moment(postDoc.created_at).fromNow(true);



        let userDoc: AngularFirestoreDocument<any> = this._DB.getUserByid('zVrLvAtp9Pe');//postDoc.created_by             
        let created_by: Observable<any> = userDoc.valueChanges();

        created_by.subscribe(u => {
            postDoc.created_by = u;
        });

        this.timelineData[i] = postDoc;

      }         
    });
  }

  loadMore(infiniteScroll?) {

    let morePosts: AngularFirestoreCollection<Post> = this._DB.get_all_posts(this.country, this.limit, this.startAfter);          

    morePosts.valueChanges().subscribe((items) => {
      let t = this.timelineData.length;

      for (var i = 0, len = items.length; i < len; i++) {

        let postDoc = items[i];

        //for slides view
        postDoc.slidesPerView = 1;
        postDoc.slidesPager = false;
        if (postDoc.images && postDoc.images.length && !postDoc.video){
            if(postDoc.images.length > 1){
                postDoc.slidesPerView = 1.1;
                postDoc.slidesPager = true;
            }
        }

        if(postDoc.created_at)
            postDoc.created_at = moment(postDoc.created_at).fromNow(true);



        let userDoc: AngularFirestoreDocument<any> = this._DB.getUserByid('zVrLvAtp9Peh8Bl3vfIPQh7GP972');//postDoc.created_by            
        let created_by: Observable<any> = userDoc.valueChanges();

        created_by.subscribe(u => {
            postDoc.created_by = u;
        });


        this.timelineData[i + t] = postDoc;


      }


      infiniteScroll.complete();

      if (items.length < this.limit) {
        console.log("Disabling timeline scroll");
        infiniteScroll.enable(false);
      }

    });
  }

  doInfinite(infiniteScroll) {
    console.log('Begin async operation');   
    this.startAfter = this.timelineData[this.timelineData.length - 1].id;
    this.loadMore(infiniteScroll);
    console.log('Async operation has ended');
  }

  getUserData(){
    ...
  }

home.html:

<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>

  </ion-navbar>
</ion-header>

<ion-content no-padding scrollable (scrollPosition)="scrollHandler($event)">

  <ng-template #loading>No Data...</ng-template>

  <div *ngIf="timelineData;else loading;"> 

    <ion-card *ngFor='let post of timelineData'>

      <ion-item>
        <ion-avatar item-start>
          <img src="{{post.created_by?.photoURL}}" *ngIf="post.created_by?.photoURL">
          <img src="assets/custom_imgs/default-user-image.png" *ngIf="!post.created_by?.photoURL">
        </ion-avatar>

        <h2 *ngIf="post.created_by?.displayName">{{post.created_by?.displayName}}</h2>
        <h2 *ngIf="!post.created_by?.displayName">Syrian User</h2>

        <p>{{post?.created_at}}</p>
      </ion-item>


      <ion-card-content>
        <p>{{post?.text}}</p>
      </ion-card-content>


      <video *ngIf="post?.video" width="100%" height="auto" preload="metadata" muted="true" playsinline webkit-playsinline controls>
        <source src="{{post?.video}}#t=0.1" type="video/mp4">
      </video>



      <ion-slides *ngIf="post?.images && !post?.video" #slider spaceBetween="10" [slidesPerView]="post?.slidesPerView" effect="slide" [pager]="post?.slidesPager" paginationType="bullets" parallax="true" zoom="true">
        <ion-slide *ngFor="let image of post.images" [ngStyle]="{'background' : 'url(' + image + ')'}"></ion-slide>
      </ion-slides>


      <ion-item *ngIf="post?.likes_count > 0 || post?.comments_count > 0">
        <span class="likes-count" *ngIf="post?.likes_count > 0" item-start>{{post?.likes_count}} likes</span>
        <span class="comments-count" *ngIf="post?.comments_count > 0" item-end>{{post?.comments_count}} comments</span>
      </ion-item>
      <hr />


      <ion-row text-center>

        <ion-col>
          <button ion-button icon-start clear small [color]="post?.userIsLike ? 'primary' : 'darkgray'">
            <ion-icon name="thumbs-up"></ion-icon>
            <div>like</div>
          </button>
        </ion-col>

        <ion-col>
          <button ion-button icon-start clear small color="darkgray">
            <ion-icon name="text"></ion-icon>
            <div>comments</div>
          </button>
        </ion-col>

        <ion-col>
          <button ion-button icon-start clear small color="darkgray">
            <ion-icon name="share-alt"></ion-icon>
            <div>share</div>
          </button>
        </ion-col>

      </ion-row>

    </ion-card>

  </div>

  <ion-infinite-scroll (ionInfinite)="doInfinite($event)">
   <ion-infinite-scroll-content></ion-infinite-scroll-content>
  </ion-infinite-scroll>


</ion-content>

无限滚动效果很好,向下滚动时可以加载更多项目,但是当我从Firebase控制台更新任何对象时,数据将通过“ loadMore function”进行更新,但包含这些项目的重复项。

我试图基于'timelineData.length'更新数组,但是它不起作用,并且在更改时仍会加载重复项

let t = this.timelineData.length;

然后(在foreach末尾)

this.timelineData[i + t] = postDoc;

对不起,我的英语:(

提前谢谢。

0 个答案:

没有答案