Angular2 RxJS Observable Search字段过滤链

时间:2017-05-17 15:49:44

标签: angular rxjs array-filter

我有一个Angular2 CLI应用程序,其搜索组件需要进行深度搜索。我的意思是,当用户在过去40年内用出生日期的名字搜索所有用户时,开始输入名称和searchService的字母,然后首先获取名称中包含这些字母的所有用户对象,然后是每个对象上的另一个过滤器,用于比较出生日期(存储在由用户标识链接的另一个对象中),并仅返回其dob在过去40年内的用户对象。

搜索字段

<input (keyup)="search()" type="text" [(ngModel)]="searchTerms" />

结果

<div *ngFor="let result of finalResults | async">
   {{result.name}}
</div>

组件代码

finalResults = searchTerms
  .debounceTime(300)      
  .distinctUntilChanged()   
  .switchMap(term => {
    return searchService1.search(term)
      .map(items => items.filter(item => {
           searchService2.search(item.id)
            .map(results => results.filter(result => result.dob>1977))
            })
      )
  })
  .catch(handleError);

我看到的行为是,只要搜索词具有匹配的字母,结果就包含这些用户,但忽略了dob过滤器。

1 个答案:

答案 0 :(得分:0)

问题是您尝试使用异步值进行同步过滤。 searchService2以异步方式返回,但您正尝试根据Observable的值进行过滤,这始终是真实的。

您需要将第二个流展平为第一个流。

以下内容应更符合您的需求。

finalResults = searchTerms
  .debounceTime(300)      
  .distinctUntilChanged()
  // Flatten each search result from the first search service 
  .switchMap(term => searchService1.search(term))
  // Flatten the returned items into the stream
  .switchMap(items => items)
  // Initiate the second search and map the dob into the returned object
  .switchMap(
    item => searchService2.search(item.id)
  )
  // Flatten the secondary results
  .switchMap(items => items)
  // Filter each of the items
  .filter(({dob}) => dob > 1977)  
  .catch(handleError);