Ionic 3 - 使用异步数据更新Observable

时间:2017-05-28 16:45:40

标签: javascript firebase asynchronous ionic2 ionic3

对于社交媒体应用,我有一组使用AngularFire 2通过其ID引用的Feed对象。一旦这些ID中的每一个都从存储实际feed对象的数据库中提取了相关数据,我希望用这些信息更新feedCards Observable对象,这样我就可以在HTML中异步显示一个feed对象集合。这是一个非常令人困惑的事件链,所以让我为你总结一下。

  

循序渐进的方法

  1. displayFeed()NavController加载feed页面上的Main组件之前调用。
  2. displayFeed()获取twiner项,该项基本上是用户个人资料项,然后将用户个人资料存储在userProfile变量中。
  3. 加载用户配置文件后,全局feedCards Observable设置为loadFeed(),返回一个Observable数组。
  4. loadFeed()使用id全局对象的userProfile值来加载存储在用户个人资料中的Feed引用列表。
  5. 然后订阅此快照,并将本地feed变量设置为等于Feed引用的结果列表。
  6. loadFeed返回一个Observable对象,其中feed引用列表由每个Feed引用包含的数据映射。
  7. pullFeedData(number)接受对Feed对象的引用,并返回带有关联Feed数据的observable。
  8.   

    什么有用

    • alert(JSON.stringify(feedData));会提醒正确的feed对象

    • 基本上所有其他内容。

      

    什么行不通

    • feed.map(...不会更新Feed数组,因为pullFeedData(number)会异步提取并返回feedData。因此,alert(JSON.stringify(data));中的displayFeed()提醒[null]
      

    代码

    feed.ts

       userProfile:any;
       feed: FirebaseListObservable<any>;
       feedData: FirebaseObjectObservable<any>;
    
       feedCards: Observable<any[]>;
    
       constructor(public db: AngularFireDatabase, public nativeStorage: NativeStorage) {}
    
       displayFeed():void {
            this.nativeStorage.getItem('twiner').then((res) => {
                  this.userProfile = res;
                  this.feedCards = this.loadFeed();
                  this.feedCards.subscribe((data)=>{
                        alert(JSON.stringify(data));
                  })
            });
      }
    
      loadFeed():Observable<any[]> {
            var feed;
            this.feed = this.db.list('/twiners/' + this.userProfile.id + '/feed', { preserveSnapshot: true });
            this.feed.subscribe((snapshots)=>{feed = snapshots});
            return Observable.of(feed.map((snapshot) => {
                  this.pullFeedData(snapshot.val()).subscribe((feedData)=>{
                        alert(JSON.stringify(feedData));
                        return feedData;
                  });
            })).delay(1000);
      }
    
      pullFeedData(twine:number):any {
            return this.db.object('/twines/' + twine, { preserveSnapshot: true });
      }
    

    feed.html

    <ion-content fullscreen scroll="true" overflow-scroll="true">
          <ion-card *ngIf="feedCards | async">feedCards exist</ion-card>
          <twine-feed-card *ngFor="let feedCard of feedCards | async"
                [data]="feedCard"
          ></twine-feed-card>
    </ion-content>
    
      

    摘要

    feed.map不会使用Feed对象更新feed,因为新数据是异步提取的。我需要修复此问题。

    谢谢!

1 个答案:

答案 0 :(得分:6)

订阅的observable不返回值。它返回一个Subscription对象,您可以使用该对象稍后取消订阅。

您可以在调用期间使用switchMap从第一个observable切换到下一个observable并返回值。 您也可以使用forkJoin来调用一个observable数组,并等到订阅中返回值数组。 首先将feed类变量声明为Observable

feed: Observable<any>;

然后在loadFeed():Observable<any[]>

return this.feed.switchMap((snapshots) => {
             let observableArray = [];
             snapshots.forEach(snapshot =>{
                 observableArray.push(this.pullFeedData(snapshot.val()));
             });
             return Observable.forkJoin(observableArray)
        })