Rxjs 如何根据每个值的可观察属性筛选出可观察值
假设我有一个可观察的项目Rxjs 如何根据每个值的可观察属性筛选出可观察值,rxjs,Rxjs,假设我有一个可观察的项目 let items$ = Observable<Item[]> 接收当前选定的所有项目列表的最佳方式是什么?我的解决方案看起来不太正确: items$.pipe( switchMap(items => combineLatest(items.map(item => item.isSelected$.pipe( map(isSelected =>
let items$ = Observable<Item[]>
接收当前选定的所有项目列表的最佳方式是什么?我的解决方案看起来不太正确:
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))
)))
它是有效的,我以前也用过它,但对于我经常要做的事情来说,它是如此复杂的构造。一定有更好的办法
注意:订阅者需要所有选定项目的列表,而不是单个项目的流
示例:
项目$
将发出以下列表:
[{id: 1, isSelected$: of(true)},
{id: 2, isSelected$: of(false)},
{id:3, isSelected$: of(true)}]
作为订阅的结果,我们希望获得以下列表:
[{id: 1}, {id: 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$
的通知,这是一个数组,并将其转换为一个可观察的对象,该对象同时发出一个项目
然后,键位于作为参数传递给mergeMap
的函数中
item.isSelected
返回要用于筛选的可观察项。我们通过map
应用一个变换,将其转化为一个对象,该对象包含两个属性:选择标准和整个项目
其余的只是根据选择标准进行过滤,然后再次转换以返回项
我已经用以下测试数据测试了上述代码
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)},
]
);
这肯定比我的方法好。但是,最后如何收集所有项目作为列表?我可能忘了明确提到,结果必须是一个项目列表。可能toArray
操作符就是您正在寻找的,它似乎是toArray
在源可观测完成时发出的。但是我想,items$
永远不会完成,那么我们得到数组了吗?是的,你是对的,它会在源可观测完成时发出。如果你想在最后列出一个清单,这是非常合乎逻辑的。你能详细说明一下你想要什么样的名单吗?如果items$
从未完成,该列表会是什么样子?items$
是一个长期存在的可观察对象,它会发出项目列表。请参见编辑。
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)},
]
);