問題描述
對于社交媒體應用程序,我有一組使用 AngularFire 2
由其 ID 引用的提要對象.一旦這些 ID 中的每一個都從存儲實際提要對象的數據庫中提取了相關數據,我希望使用此信息更新 feedCards
可觀察對象,以便我可以異步顯示提要對象的集合.HTML.這是一個相當混亂的事件鏈,所以讓我為你總結一下.
循序漸進的方法
displayFeed()
在NavController
加載Main
頁面上的feed
組件之前調用.displayFeed()
獲取twiner
項,它本質上是一個用戶配置文件項,然后將用戶配置文件存儲在userProfile
變量中.- 加載用戶配置文件后,全局
feedCards
Observable 將設置為等于loadFeed()
,返回一個 Observable 數組. loadFeed()
使用userProfile
全局對象的id
值來加載存儲在用戶配置文件中的提要參考列表.- 然后訂閱此快照并將本地
feed
變量設置為等于提要引用的結果列表. loadFeed
返回一個 Observable 對象,其中feed
引用列表由每個提要引用包含的數據映射.pullFeedData(number)
接受對 feed 對象的引用并返回一個帶有相關 feed 數據的 observable.
<塊引用>
什么有效
alert(JSON.stringify(feedData));
提醒正確的feed
對象基本上其他的.
什么不起作用
feed.map(...
不會更新 feed 數組,因為pullFeedData(number)
會異步拉取并返回feedData
.因此,alert(JSON.stringify(data));
indisplayFeed()
警報[null]
.
代碼
feed.ts
userProfile:any;提要:FirebaseListObservable<any>;feedData: FirebaseObjectObservable<any>;feedCards:可觀察的<any[]>;構造函數(公共數據庫:AngularFireDatabase,公共 nativeStorage:NativeStorage){}displayFeed():無效{this.nativeStorage.getItem('twiner').then((res) => {this.userProfile = res;this.feedCards = this.loadFeed();this.feedCards.subscribe((數據)=>{警報(JSON.stringify(數據));})});}loadFeed():Observable<any[]>{變種飼料;this.feed = this.db.list('/twiners/' + this.userProfile.id + '/feed', { preserveSnapshot: true });this.feed.subscribe((snapshots)=>{feed = snapshots});返回 Observable.of(feed.map((snapshot) => {this.pullFeedData(snapshot.val()).subscribe((feedData)=>{警報(JSON.stringify(feedData));返回飼料數據;});})).延遲(1000);}pullFeedData(麻線:數字):任何{return this.db.object('/twines/' + twine, { preserveSnapshot: true });}
feed.html
<塊引用>
總結
feed.map
不會用 feed 對象更新 feed
,因為新數據是異步提取的.我需要解決這個問題.
謝謝!
訂閱的 observable 沒有返回值.它返回一個 Subscription
對象,您可以稍后使用它來取消訂閱.
您可以在調用過程中使用 switchMap
從第一個 observable 切換到下一個 observable 并返回值.你也可以使用 forkJoin
來調用一個 observables 數組并等到值數組在訂閱中返回.首先將 feed
類變量聲明為 Observable
.
feed: Observable<any>;
然后在你的 loadFeed():Observable<any[]>
return this.feed.switchMap((snapshots) => {讓 observableArray = [];快照.forEach(快照 =>{observableArray.push(this.pullFeedData(snapshot.val()));});返回 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
displayFeed()
is invoked right before theNavController
loads thefeed
component on theMain
page.displayFeed()
gets thetwiner
item, which is essentially a user profile item, and then stores the user profile in theuserProfile
variable.- Once the user profile is loaded, the global
feedCards
Observable is set equal toloadFeed()
, which returns an Observable array. loadFeed()
uses theid
value of theuserProfile
global object to load the list of feed references stored in the user profile.- This snapshot is then subscribed to and the local
feed
variable is set equal to the result list of feed references. loadFeed
returns an Observable object in which thefeed
reference list is mapped by the data each feed reference contains.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 correctfeed
objectBasically everything else.
What Doesn't Work
feed.map(...
does not update the feed array becausepullFeedData(number)
pulls and returns thefeedData
asynchronously. Thus,alert(JSON.stringify(data));
indisplayFeed()
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)
})
這篇關于Ionic 3 - 使用異步數據更新 Observable的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!