我有产品服务,我想从州获得最好的产品。
我可以实现此目的的一种方法是使用rxjs如下所示:
@Injectable({ providedIn: 'root' })
export class ProductDataService extends EntityCollectionServiceBase<Product> {
bestProductsIds$ = new BehaviorSubject([]);
bestProducts$ = combineLatest([this.entities$, this.bestProductsIds$]).pipe(
map(([products, ids]) => products.filter((p) => ids.includes(p.id))),
map((products) => orderBy(product, ['createdDate', ['desc']])),
map((products) => this.toProductCard(products))
);
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用选择器:
export const selectBestProducts = createSelector(
([products, ids]) => products.filter((p) => ids.includes(p.id)),
(products) => orderBy(products, ['createdDate', ['desc']])
);
@Injectable({ providedIn: 'root' })
export class ProductDataService extends EntityCollectionServiceBase<Product> {
bestProductsIds$ = new BehaviorSubject([]);
bestProducts$ = combineLatest([this.entities$, this.bestProductsIds$]).pipe(select(selectBestProducts));
...
}
Run Code Online (Sandbox Code Playgroud)
我知道 ngrx 选择器是记忆函数,但我在这里使用combineLatest。
那么在这种情况下,两种方法有什么不同呢?或者是一样的?
简短的回答是没有区别,就像combineLatest您使用两个在幕后有记忆值的选择器的情况一样。
关于差异的长答案,如果我们转到文档selector内的实现,我们可以看到这些函数用于跟踪正在使用的任何更改,最终看起来像这样ngrx createSelectordefaultMemoizeisEqualCheck
export function isEqualCheck(a: any, b: any): boolean {
return a === b;
}
Run Code Online (Sandbox Code Playgroud)
因此,每当更改中的字段state(我们依赖于选择器内部的字段)时,相关选择器将计算它的新值。您可以使用选择器做的有趣的事情是,createSeletorFactory您可以在其中提供自己的自定义比较函数,以便在需要时进行进一步优化。
关于combineLatest选择器的使用,您几乎具有相同的效果,一旦所有可观察量都发出了值,并且每次从任何这些可观察量传递新值时,新值将在流中进一步发射,将由您的逻辑处理(关于优化最受欢迎的项目的部分),在这里您可以通过distincUntilChanged您自己的自定义比较再次使用运算符来达到相同的优化效果。
总之,两种方法的行为方式相同,唯一的区别是,在第一种情况下,选择器正在执行所需的计算,而在第二种情况下,计算是在可观察到的流中处理的combineLatest。
| 归档时间: |
|
| 查看次数: |
328 次 |
| 最近记录: |