[英]Angular Rxjs How to paginate using Behavior Subject
I'm building a filtration for products list using categories ids and doing this by using the RXJS operator BehaviorSubject
.我正在使用类别 ID 为产品列表构建过滤器,并使用 RXJS 操作符BehaviorSubject
执行此操作。
My problem is I can't infinite scroll with Behavior Subject as I can't get the previous array of data ( products ) as obviously always get the latest data I update with.我的问题是我无法无限滚动 Behavior Subject,因为我无法获取先前的数据数组( products ),因为显然总是获取我更新的最新数据。
My Service:我的服务:
private productsSource = new BehaviorSubject<Product[]>(null);
public products$: Observable<Product[]> = this.productsSource.asObservable();
async getProductsByCategory(category: string, page: string = '1'): Promise<void> {
const products = await this.http.get<Product[]>(`${environment.host + this.wooPath}products`, {
params: {
...environment.configtations,
category,
page,
lang: this.language,
per_page: '6',
not_tags: 'component'
}
})
.toPromise();
this.productsSource.next(products);
}
My loadMore ( Pagination ):我的加载更多(分页):
async loadData(event) {
// what next?
}
Change this.productsSource.next(products);
更改this.productsSource.next(products);
to:到:
this.products.next({
previous: this.products.value.current
current: products
});
And the definition:和定义:
private productsSource = new BehaviorSubject<any>(null);
// You could also make a type for that like:
// { previous: Product[], current: Product[] }
And then you always have the previous one and the current one.然后你总是有前一个和当前的。
If you want to achive an infinite scroll, I would suggest you to change push all values into a dedicated array like:如果您想实现无限滚动,我建议您将所有值更改为专用数组,例如:
products$.subscribe((value) => {
this.someProductsArray = [...this.someProductsArray, ...value];
});
I found a way to my situation that perfect fit,我找到了一种完美适合我的情况的方法,
The code for it:它的代码:
My service: Just returning a products list as a promise from the getProductsByCategory
method:我的服务:只是从getProductsByCategory
方法返回一个产品列表作为承诺:
/**
* @name getProductsByCategory
* @param category
* @param page
*/
async getProductsByCategory(category: string, page: string = '1'): Promise<Product[]> {
// getting products
const products = await this.http.get<Product[]>(`${environment.host + this.wooPath}products`, {
params: {
...environment.configtations,
category,
page,
lang: this.language,
// per_page: '6',
not_tags: 'component'
}
})
.toPromise();
return products;
}
Then create a new method that returns the productsSource
:然后创建一个返回productsSource
的新方法:
filteringProduct() {
return this.productSource;
}
On Component : in ngOnInit
giving it an initial value:在组件上:在ngOnInit
给它一个初始值:
async ngOnInit() {
// get the category id
const id = this.route.snapshot.paramMap.get('id');
this.categoriesIds = id;
// get gategory and its sub categories Or Prodicts by category id
[this.category, this.subCatergories] = await Promise.all([
this.wooService.getCategoryById(id),
this.wooService.getSubCategories(id)]);
// setting products
this.wooService
.filteringProduct()
.next(
await this.wooService.getProductsByCategory(this.categoriesIds)
);
this.wooService.products$
.pipe(
takeUntil(this.unsubscribe)
)
.subscribe(data => this.products = data);
}
My loadMore
Methode:我的loadMore
:
async loadData(event) {
// next page number
this.currentPage++;
// const id = this.category.id.toString();
// next page content
const nextPage = await this.wooService.getProductsByCategory(
this.categoriesIds,
this.currentPage.toString()
);
// concat all together
this.products = this.products.concat(nextPage);
// compelete the loading
event.target.complete();
// checking if all data loaded from the server
if (nextPage.length === 0) {
this.infinite = false;
}
}
You can use count()
operator to store the page number and just a normal subject will do the job.您可以使用count()
运算符来存储页码,只需一个普通主题即可完成这项工作。
currentPage=Subject();
getProduct=(page)=>
this.http.get<Product[]>(`${environment.host + this.wooPath}products`, {
params: {
...environment.configtations,
category,
page,
lang: this.language,
per_page: '6',
not_tags: 'component'
}
})
data=loadMore.pipe(
count(),
mergeMap(page=>getProduct(page)),
scan((acc,curr)=>{
return acc.concat(cur.res)
},[])
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.