【问题标题】:Ionic 3 - Update Observable with Asynchronous DataIonic 3 - 使用异步数据更新 Observable
【发布时间】:2017-05-28 16:45:39
【问题描述】:

对于社交媒体应用程序,我有一组由其 ID 引用的提要对象,使用 AngularFire 2。一旦这些 ID 中的每一个都从存储实际提要对象的数据库中提取了相关数据,我希望使用此信息更新 feedCards Observable 对象,以便我可以在我的 HTML 中异步显示提要对象的集合。这是一个相当混乱的事件链,所以让我为你总结一下。

循序渐进的方法

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

什么有效

  • 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,因为正在异步提取新数据。我需要解决这个问题。

谢谢!

【问题讨论】:

  • 您是否尝试在区域内运行它..? (我以前用listobservables,现在用事件发射器来实现这个实时功能)
  • @RajaYogan 您介意重申如何在区域中使用此功能吗?总之,我不知道那是什么。
  • 没有问题..您是否在警报中获得了此处的数据..? this.feedCards.subscribe((data)=>{ alert(JSON.stringify(data)); })
  • @RajaYogan 不,我不知道。我把它放在我原来的问题中。
  • 我觉得你需要看看promises。他们基本上设置了一个回调函数,在异步行为完成后被调用。

标签: javascript firebase asynchronous ionic2 ionic3


【解决方案1】:

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

您可以在调用期间使用switchMap 从第一个可观察对象切换到下一个可观察对象并返回值。 你也可以使用forkJoin,它会调用一个可观察的数组并等到该数组在订阅中返回。 首先将feed 类变量声明为Observable

feed: Observable<any>;

然后在你的loadFeed():Observable&lt;any[]&gt;

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

【讨论】:

  • 终于让我的代码在您的回答之后使用 forEach 方法工作。非常感谢! ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
  • 2018-10-11
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
相关资源
最近更新 更多