角度可观察的过滤

时间:2020-05-17 15:21:38

标签: angular filter rxjs observable

我遇到了用数组过滤可观察对象的问题。 让我解释一下...

我有:

  • products $:可观察;
  • filteredProducts $:可观察;
  • selectedFilters = [['过滤器名称',idOfFilter],['过滤器名称',idOfFilter]]; (开头是空的)

这是产品对象的结构: Here is the structure of a product object

这是我的过滤器数组的结构 enter image description here

我想将过滤的结果设置为filteredProducts。 对于过滤器,我必须检查产品的过滤器数组是否包含过滤器的名称,以及产品值数组的是否包含过滤器ID。

到目前为止,我一直在写这篇文章,但我不知道如何真正过滤我的Observable ...

export class ProductsFilterComponent extends BaseComponent implements OnInit {
    @Select(FiltersState.getAllFilters) filters$: Observable<any>;
    @Input() products$: Observable<Product[]>;
    filteredProducts$: Observable<Product[]>;

    public tempProducts$: Observable<Product[]>;
    public selectedFilters = [];

    constructor(
        private store: Store) { super(); }

    ngOnInit() {
        this.store.dispatch(new GetAllFilters());
        this.uns = this.products$.subscribe(res => console.log('products from filter component', res));
    }

    private filterProducts() {
      this.filteredProducts$ = this.products$.pipe(
          map(productsArray =>
              productsArray.filter(product => {
                  product.filters.filter(filters => filters.values.includes(5));
              }))
      );
  }

}

3 个答案:

答案 0 :(得分:0)

您可以在$stmt->free_result();中声明您的filteredProducts$

ngOnInit()

因此,每次您的ngOnInit() { this.filteredProducts$ = this.products$.pipe( switchMap(products => { return this.filters$.pipe( startWith([]), map(filters => { return products.filter(/* apply your filter*/) }) ); }) ) } 更改时,该过滤器都会应用。 使用filters$,您可以说Observable startWith()在开始发出源Observable发出的项目之前先发出一个空数组。

编辑:啊,您已经将filters用作@Select。我更新了答案。

答案 1 :(得分:0)

我认为这可能是一个解决方案:

this.filteredProducts$ = products$.pipe(
  map(
    productsArr => productsArr.filter(
      p => 
        p.filters.some(f => selectedFilters.some(([selectedF]) => selectedF === f.name) // Filter name
        && f.values.some(value => selectedFilters.some(([, filterId]) => filterId === value)) // Filter id
    )
  ),
)

答案 2 :(得分:0)

您可以使用combineLatest创建一个可观察流,只要任何源可观察对象发出新值,该流就会更新。

  filteredProducts$ = combineLatest(this.products$, this.filters$).pipe(
    map(([products, selectedFilters]) => {
      return products.filter(p => {
        // actual filter logic goes here
        return p.filters.some(pf => selectedFilters.some(f => pf == f));
      });
    })
  );

查看此有效的StackBlitz