对于社交媒体应用程序,我有一组使用 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));
in displayFeed()
警报 [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 the NavController
loads the feed
component on the Main
page.displayFeed()
gets the twiner
item, which is essentially a user profile item, and then stores the user profile in the userProfile
variable.feedCards
Observable is set equal to loadFeed()
, which returns an Observable array.loadFeed()
uses the id
value of the userProfile
global object to load the list of feed references stored in the user profile.feed
variable is set equal to the result list of feed references.loadFeed
returns an Observable object in which the feed
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 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)
})
这篇关于Ionic 3 - 使用异步数据更新 Observable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!