对于社交媒体应用程序,我有一组使用 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
在 Angular 2/Typescript 中使用 IScrollUse IScroll in Angular 2 / Typescript(在 Angular 2/Typescript 中使用 IScroll)
Anime.js 在 Ionic 3 项目中不起作用anime.js not working in Ionic 3 project(Anime.js 在 Ionic 3 项目中不起作用)
Angular 2:在本地 .json 文件中找不到文件Angular 2: file not found on local .json file(Angular 2:在本地 .json 文件中找不到文件)
在 Ionic 2 中,如何创建使用 Ionic 组件的自定义指In Ionic 2, how do I create a custom directive that uses Ionic components?(在 Ionic 2 中,如何创建使用 Ionic 组件的自定义指令?)
将 ViewChild 用于动态元素 - Angular 2 &离子2Use ViewChild for dynamic elements - Angular 2 amp; ionic 2(将 ViewChild 用于动态元素 - Angular 2 amp;离子2)
如何在 ionic2 中的 pop() 之后重新加载离子页面How to reload the ion-page after pop() in ionic2(如何在 ionic2 中的 pop() 之后重新加载离子页面)