离子3 - 更新与异步数据可观察 [英] Ionic 3 - Update Observable with Asynchronous Data

查看:186
本文介绍了离子3 - 更新与异步数据可观察的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


循序渐进的方法

$ b在


$ b


  1. displayFeed() > NavController 在 Main 页面上加载 feed 组件。

  2. displayFeed()获取 twiner 项目,这本质上是一个用户配置文件项目,用户配置文件在 userProfile 变量中。

  3. 加载用户配置文件后,全局 feedCards Observable设置为等于 loadFeed(),它返回一个Observable数组。
  4. loadFeed()使用 userProfile 全局对象的 id 值来加载这个快照然后被订阅,并且本地 feed 变量被设置为等于结果列表的
  5. loadFeed 返回一个Observable对象,其中 feed 参考列表由每个提要引用包含的数据映射。
  6. pullFeedData(number)引用一个提要对象并返回一个




有用的功能





  • alert(JSON.stringify(feedData)); c $ c> feed object


  • 基本上就是其他的东西。

  • >


    无效




    • feed.map(... 不会更新提要数组,因为 pullFeedData(number)异步返回 feedData 。因此, alert(JSON.stringify(data)); displayFeed() alerts [

      $ b


      代码


    • / blockquote>

      feed.ts

        userProfile:any; 
      feed:FirebaseListObservable< any>;
      feedData:FirebaseObjectObservable< any>;

      feedCards:Observable< any []>;

      构造函数(公共数据库:AngularFireDatabase,公共nativeStorage:NativeStorage){}
      $ b displayFeed():void {
      this.nativeStorage.getItem('twiner') ((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}); (快照)=> {feed = snapshots});
      this.feed.subscribe((snapshots)=> {feed = snapshots}); ($ 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 =trueoverflow-scroll =true> 
      < ion-card * ngIf =feedCards | async> feedCards exists< / ion-card>
      < twine-feed-card * ngFor =let feedCards | async
      [data] =feedCard
      >< / twine-feed-card>
      < / ion-content>




      小结

      feed.map 不会更新 feed ,因为新的数据正在被异步拉。

      谢谢!

      解决方案

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



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

        feed:Observable< any>然后在你的 loadFeed()中:Observable< any []>  $ / pre> 

      / code>

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


      For a social media app, I have a collection of feed objects referenced by their IDs using AngularFire 2. Once each of these IDs has its relevant data pulled from the database that stores the actual feed objects, I wish to update the feedCards Observable object with this information so I can asynchronously display a collection of feed objects in my HTML. It's a pretty confusing chain of events, so let me summarize it for you.

      Step-by-step Approach

      1. displayFeed() is invoked right before the NavController loads the feed component on the Main page.
      2. displayFeed() gets the twiner item, which is essentially a user profile item, and then stores the user profile in the userProfile variable.
      3. Once the user profile is loaded, the global feedCards Observable is set equal to loadFeed(), which returns an Observable array.
      4. loadFeed() uses the id value of the userProfile global object to load the list of feed references stored in the user profile.
      5. This snapshot is then subscribed to and the local feed variable is set equal to the result list of feed references.
      6. loadFeed returns an Observable object in which the feed reference list is mapped by the data each feed reference contains.
      7. pullFeedData(number) takes in a reference to a feed object and returns an observable with the associated feed data.

      What Works

      • alert(JSON.stringify(feedData)); alerts the correct feed object

      • Basically everything else.

      What Doesn't Work

      • feed.map(... does not update the feed array because pullFeedData(number) pulls and returns the feedData asynchronously. Thus, alert(JSON.stringify(data)); in displayFeed() alerts [null].

      Code

      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>
      

      Summary

      feed.map does not update feed with feed objects because the new data is being pulled asynchronously. I need a fix for this.

      Thank you!

      解决方案

      A subscribed observable does not return a value. It returns a Subscription object which you can use to unsubscribe later.

      You can use switchMap to switch from first observable to the next during the call and return the values. Also you can use forkJoin which will call an array of observables and wait till the array of values is returned in subscription. First declare feed class variable as an Observable.

      feed: Observable<any>;
      

      Then in your loadFeed():Observable<any[]>

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

      这篇关于离子3 - 更新与异步数据可观察的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆