2017-05-28 36 views
6

W przypadku aplikacji mediów społecznościowych mam kolekcję obiektów danych źródłowych, do których odwołują się ich identyfikatory, używając AngularFire 2. Gdy każdy z tych identyfikatorów ma odpowiednie dane wyciągnięte z bazy danych, która przechowuje faktyczne obiekty kanału, chcę zaktualizować obiekt obserwowalny feedCards za pomocą tych informacji, aby móc asynchronicznie wyświetlać kolekcję obiektów kanału w moim kodzie HTML. To dość mylący ciąg wydarzeń, więc pozwól mi podsumować go dla Ciebie.Ionic 3 - aktualizacja możliwa do zaobserwowania za pomocą danych asynchronicznych

Krok po kroku podejścia

  1. displayFeed() jest wywoływana tuż przed NavController ładunku komponent feed na stronie Main.
  2. displayFeed() otrzymuje element twiner, który jest zasadniczo elementem profilu użytkownika, a następnie przechowuje profil użytkownika w zmiennej userProfile.
  3. Po załadowaniu profilu użytkownika globalna obserwowalna feedCards jest ustawiona na loadFeed(), która zwraca tablicę obserwowalną.
  4. loadFeed() używa wartości id obiektu globalnego userProfile w celu załadowania listy referencji kanałów przechowywanych w profilu użytkownika.
  5. Ta migawka jest następnie subskrybowana, a lokalna zmienna feed jest ustawiona na równi z listą wyników odniesień do pliku danych.
  6. loadFeed zwraca obiekt obserwowalny, w którym lista referencyjna feed jest mapowana przez dane, z których składa się każde odniesienie do pliku danych.
  7. pullFeedData(number) przyjmuje odwołanie do obiektu kanału informacyjnego i zwraca obserwowalny z powiązanymi danymi kanału.

co działa

  • alert(JSON.stringify(feedData)); alarmuje poprawne feed obiektów

  • zasadzie wszystko.

co nie działa

  • feed.map(... nie aktualizuje tablicę podawania ponieważ pullFeedData(number) naciągów i zwraca feedData asynchronicznie. Tak więc, alert(JSON.stringify(data)); w alertach .

Kod

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> 

Podsumowanie

feed.map nie aktualizuje feed z obiektami kanału, ponieważ nowe dane są pobierane asynchronicznie. Potrzebuję poprawki.

Dziękujemy!

+0

ty spróbuj uruchomić go wewnątrz stref ..? (Używałem listobservables, teraz używam emiterów zdarzeń, aby osiągnąć tę funkcję czasu rzeczywistego) –

+0

@RajaYogan Czy pamiętasz, jak używać tej funkcji w strefach? Krótko mówiąc, nie wiem, co to jest. –

+0

Brak problemów. Czy otrzymujesz dane tutaj w alarmie? this.feedCards.subscribe ((data) => { alert (JSON.stringify (dane)); }) –

Odpowiedz

6

Subskrybowany obserwowalny nie zwraca wartości. Zwraca obiekt Subscription, którego możesz użyć do anulowania subskrypcji później.

Możesz użyć switchMap, aby przełączyć się z pierwszego obserwowalnego na następny podczas połączenia i zwrócić wartości. Możesz również użyć forkJoin, która wywoła tablicę obserwowalnych i poczeka, aż tablica wartości zostanie zwrócona w ramach subskrypcji. Najpierw zadeklaruj zmienną klasy feed jako Observable.

feed: Observable<any>; 

Następnie w loadFeed():Observable<any[]>

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

W końcu dostałem mój kod działający z użyciem metody forEach po twojej odpowiedzi. Wielkie dzięki!! –