我正在尝试模拟支持分页的http请求。目前,这个请求只返回一个数字。get请求的一个参数是数据库中使用的页码。
为了更简单,考虑getData函数,它返回一个返回页码的可观察对象。
getData(page:number):Observable<number>{
return new Observable<number>(observer => {
observer.next(page)
})
}
在我的ngOnInit中,我声明了:
data$!:Observer<number>
page:number = 0
ngOnInit():void{
this.data$ = this.getData(page).pipe(
//RxJS opeartor so that the data:number received will be converted to an array
)
}
我也试图通过避免订阅()方法来声明性/反应性地编码。所以我在模板中使用的方法是
<div *ngFor="let data of data$ | async"> {{data}} </div>
最后,模拟"加载更多"特性,我在模板中添加了<button (click)="loadMore()">Load More</button>
。在组件中,
loadMore():void{
this.data$ = this.getData(++this.page).pipe(
//I want to know what should be the RxJS operator that I should use here so that the data<number> that is emitted from the observable, will be appended to this.data$.
)
}
如果我点击加载更多按钮3次,我的模板应该显示
0
1
2
只要不使用subscribe(),我对其他方法是开放的。谢谢你!
Angular有一个订阅方法来处理Observable。我认为最简单的方法就是订阅。下面是一个例子:
data: any;
loadMore(): void {
this.getData(++this.page)
.subscribe(d => {
this.data = d;
});
}
看看我首先做的所有更改。检查数据变量是否为any类型,因为我不知道你的数据响应类型是什么。让我知道它是否适合你。
在rxjs中,转换可观察数据的标准操作符是map。
用法简单,与Array.map
相似:
loadMore():void{
this.data$ = this.getData(++this.page).pipe(
map(dataIn => ({ dataIn, page: this.page }))
)
}
正如您所指出的,从组件中订阅可观察对象并不是一个好的做法(它可能会导致您陷入内存泄漏陷阱)。
你应该返回一个可观察对象(或者像你所做的那样为可观察对象设置一个变量),并从视图中使用async管道来提取其值(它根据需要订阅/取消订阅,这消除了问题):
<div>{{ (data$ | async)?.page }}</div>