rxjs根据来自其他可观察对象的值联接和过滤可观察对象

时间:2018-08-28 06:30:35

标签: rxjs

如何使用另一个可观察对象(例如SQL中的内部联接)中的值过滤可观察对象?

class Item {
    constructor(public name: string public category: string) {
    }
}

class NavItem {
    constructor(public key: string public isSelected: boolean = false) {
    }
}

// Build a list of items
let items = of(new Item('Test', 'Cat1'), new Item('Test2', 'Cat2'))
            .pipe(toArray());

// Determine the unique categories present in all the items
let navItems = from(items)
               .pipe(mergeAll(),
                     distinct((i:item) => i.category),
                     map(i=>new NavItem(i.category)),
                     toArray());

我正在建立一个多面搜索,因此,假设在UI中选择了“ Cat1” NavItem,因此我想对具有该类别的所有项目进行观察。向下过滤到选定的NavItem之后,我不确定如何引入这些项目,对其进行过滤并仅吐出那些具有选定类别的项目。这是我所拥有的:

let filteredItems = navItems.pipe(
   mergeAll(),
   filter(n => n.isSelected))
   // join to items?
   // emit only items that match a selected category?

预期结果将是

[{name: 'Test', category: 'Cat1'}]

2 个答案:

答案 0 :(得分:0)

如果我的理解正确,您想选择代表某个类别的某个navItem,然后选择所有具有该类别的items

如果这是真的,那么您可以考虑创建这样的函数或方法

selectedItems(categoryId) {
   return items.pipe(filter(item => item.category === categoryId));
}

单击navItem后,您将引发一个引用navItem的事件,并因此引起您感兴趣的类别ID。然后,您必须调用selectedItems函数并传递您选择的类别ID。这将返回一个Observable,它发出您选择的类别的所有项目。

答案 1 :(得分:0)

我终于回过头来研究了这个问题,并且找出了解决方法。我需要使用switchMap在相同上下文中将可观察对象连接在一起。然后我可以使用map发出所有相关项目:

let filteredItems = from(items)
   .pipe(mergeAll(),
         switchMap((i) => navItems
              // Get only navItems that are selected
             .pipe(filter(ni => ni.isSelected),
                   // Convert back to array so I can if there are any selected items
                   // if zero, then show all items
                   toArray(),
                   map((nav) => {
                     if(nav.lengh > 0) {
                         // If the item's category matches, return it
                         return nav.some(x => x.key == i.category) ? i : null;
                     }

                     // If no categories were selected, then show all 
                     return i;
                   })
             }),
           // Filter out the irrelevant items
           filter(x => x !== null),
           toArray()
     );