假设我有一个可观察的物品
let items$ = Observable<Item[]>
每个项目都有一个属性isSelected$
,它本身是一个可观察的:
private isSelected$: Observable<boolean>
接收当前所选所有项目列表的最佳方法是什么?我的解决方案看起来不太正确:
items$.pipe(
switchMap(items =>
combineLatest(items.map(item =>
item.isSelected$.pipe(
map(isSelected => ({item: item, isSelected: isSelected})))),
map(items => items.filter(item => item.isSelected).map(item => item.item))
)))
它可以工作并且我以前使用过它,但是对于我经常要做的事情来说,它是如此复杂。必须有更好的方法。
注意:订户需要所有选定项目的列表,而不是单个项目的流。
示例:
items$
将发出以下列表:
[{id: 1, isSelected$: of(true)},
{id: 2, isSelected$: of(false)},
{id:3, isSelected$: of(true)}]
作为我们的订阅结果,我们想获取列表:
[{id: 1}, {id: 3}]
答案 0 :(得分:3)
您可能想尝试类似的东西
.pipe(
switchMap(
items => from(items).pipe(
mergeMap(item => item.isSelected$.pipe(map(sel => ({sel, item})))),
filter(data => data.sel),
map(data => ({id: data.item.id})),
toArray()
)
),
)
首先,我们接收items$
(它是一个数组)的通知,并将其转换为一个Observable,它在此时发出一个项目。
然后键在函数中作为参数传递给mergeMap
。
item.isSelected
返回用于过滤的Observable<boolean>
。对于此类可观察对象,我们通过map
进行了转换,将其转换为具有2个属性的对象:选择标准和整个项目。
其余的只是根据选择标准进行过滤,然后再次转换以返回item
。
我已经用以下测试数据测试了上面的代码
const items$ = of(
[
{id: 1, isSelected$: of(true)},
{id: 2, isSelected$: of(false)},
{id: 3, isSelected$: of(true)},
{id: 4, isSelected$: of(true)},
],
[
{id: 10, isSelected$: of(true)},
{id: 20, isSelected$: of(true)},
{id: 30, isSelected$: of(false)},
{id: 40, isSelected$: of(false)},
]
);