假设我有一个可观察的项目
let items$ = Observable<Item[]>
Run Code Online (Sandbox Code Playgroud)
每个 Item 都有一个 property isSelected$,它本身就是一个 Observable:
private isSelected$: Observable<boolean>
Run Code Online (Sandbox Code Playgroud)
接收当前选定的所有项目的列表的最佳方式是什么?我的解决方案看起来不太正确:
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))
)))
Run Code Online (Sandbox Code Playgroud)
它很有效,我以前也用过它,但对于我必须经常做的事情来说,它的结构非常复杂。一定会有更好的办法。
注意:订阅者需要所有选定项目的列表,而不是单个项目的流。
示例:
items$将发出以下列表:
[{id: 1, isSelected$: of(true)},
{id: 2, isSelected$: of(false)},
{id:3, isSelected$: of(true)}]
Run Code Online (Sandbox Code Playgroud)
作为我们订阅的结果,我们希望获得列表:
[{id: 1}, {id: 3}]
Run Code Online (Sandbox Code Playgroud)
你可能想尝试这样的事情
.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()
)
),
)
Run Code Online (Sandbox Code Playgroud)
首先,我们获取 的通知items$,它是一个数组,并将其转换为一次发出一项的 Observable。
关键在于作为参数传递给 的函数mergeMap。
item.isSelected返回Observable<boolean>用于过滤的 。对于这样的 Observable,我们应用一个转换 viamap将其转换为一个拥有 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)},
]
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1663 次 |
| 最近记录: |