无限滚动正在更新我在Angular10中的所有observables
有没有办法让我的最后一篇文章从第一次调用到不被下一次调用相同的函数覆盖?
换句话说,我有一个这样的 API 路由:
{{url}}?/page=1&limit=3
// page represents a param that i can manipulate incoming posts;
// limit represents how many posts will show with the call;
这条路线返回了我 3 个帖子,但是在我更改后,我page=2
从所有帖子中获得了接下来的 3 个帖子,而我以前的帖子被覆盖了..
再次更新
//这是获取帖子的服务;
allPosts$;
isLastPage = false;
currentPage = 0;
pageNumberSubject = new BehaviorSubject<number>(1);
pageSizeAction$ = this.pageNumberSubject.asObservable();
getSimplePosts(): Observable<any[]> {
return this.pageSizeAction$.pipe(
concatMap((pgNum: number): Observable<SimplePosts[]> =>
this.http.get<SimplePosts[]>(this._allPostsAPI, {
params: {
page: pgNum.toString(),
limit: "3"
}
})
),
scan((allPosts: SimplePosts[], pageUsers: SimplePosts[]) => [...allPosts, pageUsers], []),
tap((posts: SimplePosts[]) => console.log(JSON.stringify(posts))))
}
nextPage() {
this.currentPage += 1;
this.pageNumberSubject.next(this.currentPage);
}
// old implementation;
getAllPosts(page, limit) {
return this.http.get(`${this._allPostsAPI}?page=${page}&limit=${limit}`, httpOptions);
}
如何在我的组件中使用它?
我无法在我的组件中实现该功能,因为我绕过了令牌并且它们在服务中相处得很好。
这真的很难......我花了很多时间试图弄清楚,但现在对我来说太具有挑战性了..我现在会回滚一切。如果我能找到一种方法来做到这一点,我一定会为每个需要它的人更新它。
//这是我使用无限滚动的组件;
personSubject = new BehaviorSubject<any>(null);
person$: Observable<any> = this.personSubject.asObservable();
private destroy$ = new Subject();
constructor(){
//first initialise posts as first page ,
//then after the user scrolls down it activates the doInfinite() function;
this.authService.getSimplePosts().pipe(takeUntil(this.destroy$))
.subscribe((res: any) => {
console.log(res);
res.map((simplePosts: any) => {
console.log(simplePosts);
this.personSubject.next(simplePosts.data.post);
this.userGallery = simplePosts.data.post.forEach(imgIndex => {
imgIndex.galleryImages = imgIndex.images.map((image: any, index: number) => {
return new Image(
index,
{ //modal
img: image,
extUrl: image,
title: image,
},
)
});
});
});
})
}
doInfinite(infiniteScroll) {
setTimeout(() => {
console.log(this.allPosts$);
//here i call the function and it works , but my observables are still gone :D
this.authService.nextPage();
this.authService.getSimplePosts().pipe(takeUntil(this.destroy$), share()).subscribe((res: any) => {
console.log(res);
res.map((simplePosts: any) => {
console.log(simplePosts);
this.personSubject.next(simplePosts.data.post);
this.userGallery = simplePosts.data.post.forEach(imgIndex => {
imgIndex.galleryImages = imgIndex.images.map((image: any, index: number) => {
return new Image(
index,
{ //modal
img: image,
extUrl: image,
title: image,
},
)
});
});
});
})
console.log(infiniteScroll)
infiniteScroll.target.complete();
}, 1000);
}
** 编辑;** 这是最后阶段,我按照你的 stackblitz 做了,但是在我向下滚动后,我的 observables 被覆盖并且页面没有连接,它再次调用同一个页面。帮助?!
回答
您可以使用scan()新检索到的项目并将其添加到保留项目的数组中。但是您需要小心,因为如果您在用户在应用程序中导航时重新检索,则最终可能会在保留的数组中得到重复的信息。
更新:以下演示了如何将scan运算符与分页一起使用。
注意:这假设页面按顺序前进,没有后退或跳过页面。
allPosts$ = this.pageSizeAction$.pipe(
concatMap(page =>
this.http.get<Post[]>(this.postUrl, {
params: {
_page: page.toString(),
_limit: "2"
}
})
),
scan((acc, value) => [...acc, ...value])
);
扫描采用累积值 ( acc),默认情况下从第一组检索到的数据开始。它接受新检索到的值 ( value)。因此,这使用数组扩展语法将每个数组(原始和新检索到的集合)的值扩展到一个新数组中。
你可以在这里找到一个有效的 stackblitz:https ://stackblitz.com/edit/angular-paging-api-deborahk