rxjs angular 2:具有多个术语的搜索过滤器

时间:2017-06-19 08:31:29

标签: angular rxjs angular2-services rxjs5

我正在尝试使用多个术语实现搜索。 N chart flow of want i tried to implement

我读过这篇博客:https://netbasal.com/manage-your-filters-like-a-pro-in-angular-with-combinelatest-e7b0204be2df类似的情况。但我不明白我如何用动态的observables(搜索术语输入)来实现它。 假设我有30个搜索字词的过滤器。简单的解决方案是将combineLatest用于所有搜索条件组件,但效率不高。 我的目标是在第一次改变时订阅可观察者。

我试图将combineLatest运算符与动态数组一起使用,但它没有用:(。

我的代码:

import {Component, OnInit, Input, ViewChildren, QueryList, AfterViewInit} from '@angular/core';
import {Table} from "../../models/table";
import {InputFilterComponent} from "../types/input-filter/input-filter.component";
import {Observable} from "rxjs/Observable";

@Component({
  selector: '[phantom-thead-filter]',
  template: '<th>Actions</th>
  <th *ngFor="let col of cols" class="ng2-smart-th {{ col.title }}" [ngClass]="col?.class">
    <input-filter [col]="col" [table]="table"></input-filter>
  </th>
  ',
  styleUrls: ['./phantom-thead-filter.component.css']
})
export class PhantomTheadFilterComponent implements OnInit, AfterViewInit {
  @Input() cols;
  @Input() table: Table;
  @ViewChildren(InputFilterComponent) filters : QueryList<InputFilterComponent>;

  constructor() { }

  ngOnInit() {
  }

  ngAfterViewInit() {
    const filters = this.filters.map(f => f.getFilterWatcher());
    Observable.combineLatest(filters)
      .map(( filters : any[] ) => {
        filters.map((filter) => {
          return filter;
        });
      });
  }

}




import {Component, Input, OnInit} from '@angular/core';
import {FormControl} from "@angular/forms";
import {Table} from "../../../models/table";

@Component({
  selector: 'input-filter',
  template: '<input [formControl]="inputControl"
                    class="form-control"
                    type="text"
                    placeholder="input" />',
  styleUrls: ['./input-filter.component.css']
})
export class InputFilterComponent implements OnInit {
  inputControl = new FormControl();
  @Input() col;
  @Input() table: Table;
  changeFilter: any;
  constructor() { }

  ngOnInit() {
    this.changeFilter =this.inputControl.valueChanges
      .skip(1)
      .distinctUntilChanged()
      .debounceTime(400)
      .map((value: string) => {
        return value;
      }).startWith(null);
  }

  getFilterWatcher() {
    return this.changeFilter;
  }

  ngOnDestroy() {
    this.changeFilter.unsubscribe();
  }

}

2 个答案:

答案 0 :(得分:0)

CombineLatest等待所有可观察者发出第一个值。

如果您想查询即使您没有设置所有过滤器,也可以使用startWith提供虚拟的第一个空值。

const filters = this.filters.map(f => f.changeFilter.startWith(null));

Observable.combineLatest(...filters)
          .map(( filters : ActiveFilter[] ) => {
                // All filters are defined, but not all have values [null, 'search', null, null]
          });

答案 1 :(得分:0)

您可以尝试这种方法:

let listObs = [];
const searchTermA = Observable.fromEvent(this.searchInputARef.nativeElement, 'keyup').debounceTime(300).distinctUntilChanged();
listObs = [...listObs, searchTermA];

const searchTermB = Observable.fromEvent(this.searchInputBRef.nativeElement, 'keyup').debounceTime(300).distinctUntilChanged();
listObs = [...listObs, searchTermB];

Observable.combineLatest(list).subscribe(latestValues => {
    const [searchTermAValue, searchTermBValue] = latestValues;
});