javascript - Ionic 3 - Päivitä Observable asynkronisella datalla
Sosiaalisen median sovellusta varten minulla on kokoelma syötteen objekteja, joihin viitataan niiden tunnisteiden avulla käyttäen AngularFire 2-kirjastoa. Kun jokaisesta näistä tunnisteista on haettu siihen liittyvät tiedot tietokannasta, joka tallentaa varsinaiset syötteen objektit, haluan päivittää feedCards-Observable-objektin näillä tiedoilla, jotta voin asynkronisesti näyttää kokoelman syötteen objekteja HTML:ssäni. Tämä on melko hämmentävä tapahtumaketju, joten annan sinulle siitä yhteenvedon.
Askel askeleelta -lähestymistapa
displayFeed()kutsutaan juuri ennen kuinNavControllerlataafeed-komponentinMain-sivulla.displayFeed()hakeetwiner-kohteen, joka on pohjimmiltaan käyttäjäprofiilikohde, ja tallentaa sitten käyttäjäprofiilinuserProfile-muuttujaan.- Kun käyttäjäprofiili on ladattu, globaali
feedCardsObservable asetetaan yhtä suureksi kuinloadFeed(), joka palauttaa Observablen taulukon. loadFeed()käyttääuserProfile-globaalin objektinid-arvoa ladatakseen käyttäjäprofiiliin tallennetut syöteviitteiden luettelot.- Tätä tilannekuvaa tilataan sitten ja paikallinen
feed-muuttuja asetetaan yhtä suureksi kuin syötereferenssien tuloslista. loadFeedpalauttaa Observable-olion, jossafeed-viitelistä on kartoitettu sen datan mukaan, jota kukin feed-viite sisältää.pullFeedData(number)ottaa parametrikseen viitteen syötteen objektiin ja palauttaa observablen siihen liittyvillä syötedatan.
Mikä toimii
alert(JSON.stringify(feedData));näyttää oikeanfeed-objektin ilmoituksenaPeriaatteessa kaikki muu.
Mikä ei toimi
feed.map(...ei päivitä feed-taulukkoa, koskapullFeedData(number)hakee ja palauttaafeedDataasynkronisesti. Siksialert(JSON.stringify(data));displayFeed()-funktiossa näyttää[null].
Koodi
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>
Yhteenveto
feed.map ei päivitä feed-objekteja, koska uutta dataa haetaan asynkronisesti. Tarvitsen tähän korjauksen.
Kiitos!
Vastaus #1
Tilattu observable ei palauta arvoa. Se palauttaa Subscription-objektin, jota voit käyttää peruuttaaksesi tilauksen myöhemmin.
Voit käyttää switchMap-metodia siirtyäksesi ensimmäisestä observable-objektista seuraavaan kutsun aikana ja palauttaa arvot. Voit myös käyttää forkJoin-metodia, joka kutsuu observables-taulukkoa ja odottaa, kunnes arvojen taulukko on palautettu tilauksessa. Määrittele ensin feed-luokan muuttuja Observable-tyyppisenä.
feed: Observable<any>;
Sitten sinun loadFeed():Observable<any[]>
return this.feed.switchMap((snapshots) => {
let observableArray = [];
snapshots.forEach(snapshot =>{
observableArray.push(this.pullFeedData(snapshot.val()));
});
return Observable.forkJoin(observableArray)
})
