我正在寻找一个比我现有的解决方案更具可读性的解决方案。
我需要: 1)从API检索产品。它们是一个对象数组。2)根据类别等过滤产品。3)对产品进行分页并返回这些产品的分页版本。
ngOnInit() {
//This gets the products from the API
this.drinkSubscription = this.drinkService.getAllDrinks().subscribe(drinks => {
//Save products without pagination for other purposes
this.allDrinks = drinks;
//Get the parameter to filter products
this.paramSubscription = this.route.params.subscribe((params: Params) => {
//Filter the products and return a filtered array
const filteredDrinks = this.filterService.filter(drinks, params['filter'], params['name']);
//Sort products based on the selection
this.sorterSubscription = this.sorter.initialize(filteredDrinks).subscribe(sortedDrinks => {
//Create a pager that holds the paginated drinks in a property
this.pagerSubscription = this.pagerService.initializePaginatedItems(sortedDrinks, 10, 5)
.subscribe(pager => {
this.pager = pager;
this.paginatedDrinks = pager.paginatedItems;
});
});
});
});
}
排序器和分页是BehaviorSubjects的,所以我可以注入next(),但我对它们不是很确定……您可以看到缩进的级别相当高,我想知道是否有一种使用RxJS的方法可以以更易读的方式获得相同的结果。
发布于 2018-09-19 15:09:34
您应该能够使用运算符将它们组合在一起。我相信下面的方法应该是可行的。
combineLatest大致类似于Promise.all([p1,p2])
-只是它将在任何可见对象发出时发出,使用其他对象的先前值。
switchMap允许您获取从可观测对象发出的值,并将其映射到另一个可观测对象。
https://www.learnrxjs.io/operators/combination/combinelatest.html https://www.learnrxjs.io/operators/transformation/switchmap.html
例如:
let drinkObservable = this.drinkService.getAllDrinks()
let paramsObervable = this.route.params
let sub = combineLatest(drinkObservable, paramsObervable)
.pipe(switchMap(([drinks, params]) => {
this.allDrinks = drinks
let filteredDrinks = this.filterService.filter(drinks, params['filter'], params['name']);
return this.sorter.initialize(filteredDrinks)
}))
.pipe(switchMap(sortedDrinks => {
return this.pagerService.initializePaginatedItems(sortedDrinks, 10, 5)
}))
.subscribe(pager => {
this.pager = pager;
this.paginatedDrinks = pager.paginatedItems;
})
发布于 2018-09-20 05:56:18
通常,subscribe
中的subscribe
是一种“代码气味”,它隐藏了“扁平化”策略的需求,该策略需要使用扁平化运算符之一来实现,例如mergeMap
(又称flatMap
)、switchMap
、exaustMap
、concatMap
(这是mergeMap
,并将concurrency设置为1)。
在您的特定情况下,代码可能如下所示
ngOnInit() {
//This gets the products from the API
this.drinkSubscription = this.drinkService.getAllDrinks().switchMap(drinks => {
this.allDrinks = drinks;
return this.route.params)
})
.switchMap((params: Params) => {
const filteredDrinks = this.filterService.filter(drinks, params['filter'], params['name']);
return this.sorter.initialize(filteredDrinks)
})
.switchMap(sortedDrinks => this.pagerService.initializePaginatedItems(sortedDrinks, 10, 5))
.subscribe(pager => {
this.pager = pager;
this.paginatedDrinks = pager.paginatedItems;
});
});
});
});
}
https://stackoverflow.com/questions/52408401
复制相似问题