rxjs根据不同可观察对象的值连接并过滤可观察对象

rxjs根据不同可观察对象的值连接并过滤可观察对象,rxjs,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

如何使用来自另一个可观察对象的值(如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'}]

如果我理解正确,您希望选择表示某个类别的某个
navItem
,然后选择具有该类别的所有
项目

如果这是真的,那么可以考虑创建一个函数或方法,例如这个< /P>

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

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

我终于找到了解决这个问题的方法。我需要使用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()
     );              

所选项目的可观测值在哪里?这是navItems。当页面初始化时,我构建了它,默认情况下isSelected属性为false,并绑定到一个复选框列表。我需要排序的描述符比类别多得多,而且我还需要支持从会话存储中重新物质化导航状态,所以我希望更多地使用单个处理程序。你的意思是使用可以有不同的选择标准,类别是其中之一,但不是唯一一个?一旦选择了一个选择标准并给出了一个选择值,例如,一个特定的类别,那么所有其他选择标准都会重新计算并精确地显示给用户。最后一个列表是每个独立标准分区的交集。每个分区都是AND,每个分区都由OR组成。例如,项目可以是类别1或类别2,并且必须是蓝色或红色。一种非rx方式是在每个分区上进行嵌套for循环,找到选择的分区,然后在项目上循环并过滤掉数组。下一个分区拾取过滤后的数组,并以相同的嵌套方式进一步过滤它