代码之家  ›  专栏  ›  技术社区  ›  ggradnig

如何根据每个值的可观察属性筛选出可观察值

  •  2
  • ggradnig  · 技术社区  · 7 年前

    假设我有一个可观察的项目

    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}]
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Picci    7 年前

    你可以试试这样的

    .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 返回 Observable<boolean> 用于过滤。对于这样的可观察的,我们通过 map

    其余的只是根据选择标准进行过滤,然后再次转换以返回结果 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)},
        ]
    );