角度 6 过滤异步管道结果

Posted

技术标签:

【中文标题】角度 6 过滤异步管道结果【英文标题】:angular 6 filter the async pipe results 【发布时间】:2019-04-10 08:53:42 【问题描述】:

我使用 Angular 6,我想过滤异步管道的结果,然后在 UI 中呈现它们。

这是我现在的代码

this.results = this.form.get('name').valueChanges.pipe(           
  filter(formdata => formdata.name.length > 0), 
  switchMap( formdata => this.service.getNames(formdata.name)) 
);

和模板

  <div *ngIf='results | async ; let items'>
       <div *ngFor='let item of items'>item.id item.name </div>               
  </div> 

从管道中我得到了一些 id 和名称。我已经有一个 id 数组。我想过滤管道的 id,而不是渲染已经在数组中的那些。

所以,这就是我尝试做的。

array = [id:1,name:'one',id:2,name:'two'];//I already have this

管道中的新版本过滤器

this.results = this.form.get('name').valueChanges.pipe(           
  filter(formdata => formdata.name.length > 0), 
  switchMap( formdata => this.service.getNames(formdata.name)) ,
  filter(checkIfResultIdInArray())//pseudocode
);

假设checkIfResultIdInArray 是我创建的函数。过滤并返回所有不在array 中的id。所以最终出现在模板中的 ids/names 不是id:1,name:'one',id:2,name:'two'

或者我可以以某种方式过滤模板?

【问题讨论】:

不要使用Observable过滤函数,而应该使用map和数组.filter函数来代替 rxjs filter 检查是否必须传播事件。 array filter 过滤数组(你想要的)。 rxjs map 将传播新值(您想传播新的过滤数组)。所以就像 user184994 说的,对 rxjs 映射做一个数组过滤。 learnrxjs.io/operators/transformation/map.html 【参考方案1】:

@Davy 的回答是我自己会做的。然而,另一种选择是使用管道。如果您想重用此功能,这就是您要走的路。

@Pipe(name:'filterOnId')
export class FilterOnIdPipe implements PipeTransform 
    transform(list : MyObject[], acceptedIds : number[])
        return list.filter(item => acceptedIds.indexOf(item.id) > -1);
    

在模板中

<div *ngFor='let item of results | async | filterOnId : acceptedIds'>
    item.id item.name 
</div>

注意以下几点:

您使用自定义管道的方式与使用内置管道的方式相同。 您必须将管道包含在 AppModule 的声明数组中 如果你选择将管道注入到一个类中,你必须在你的 NgModule 的 providers 数组中提供它。

【讨论】:

【参考方案2】:

按照 cmets 中的建议,您可以将 AsyncPipe 替换为常规数组,或者更改发出值的值(@Davy 的解决方案很好)。

但是有一个基于模板的解决方案。我把它放在这里是为了那些不想将组件的逻辑与视图显示合并的人。

组件

result$ = of([1,2,3,4,5,6,7,8]); // for the sake of example

isAcceptedThing(thing)
  return thing%2 != 0 // accept only odd numbers

模板

<ul >
  <ng-container *ngFor="let thing of result$ | async">
    <li *ngIf="isAcceptedThing(thing)">
      filtered thing =  thing  
    </li>
  </ng-container>
</ul>

输出

过滤的东西 = 1 过滤的东西 = 3 过滤的东西 = 5 过滤的东西 = 7

【讨论】:

甚至只能在 &lt;li *ngIf="thing % 2 != 0"&gt; 这样的模板中执行此操作。对于基本的过滤操作可能会更容易,但对于复杂的操作当然会变得如此混乱。【参考方案3】:

我猜这就是你想要做的:

this.results = this.form.get('name').valueChanges.pipe(           
  filter(formdata => formdata.name.length > 0), 
  switchMap( formdata => this.service.getNames(formdata.name)) ,
  map(names => names.filter(n => checkIfResultIdInArray(n)))
);

通常,在这样的设置中,我还会添加一个 debounceTime 运算符来防止过多的请求。

【讨论】:

以上是关于角度 6 过滤异步管道结果的主要内容,如果未能解决你的问题,请参考以下文章

使用一个管道角度 2 过滤多个列

如何将管道中的版本号添加到 K6-InfluxDB-Grafana 堆栈中,以便在 grafana 中我们也可以根据版本号过滤结果

PowerSehll 中过滤管道结果

软件体系结构的第二次实验(解释器风格与管道过滤器风格)

如何正确过滤角度数组

软件体系结构的第二次实验(解释器风格与管道过滤器风格)