如何根据Angular2中对象数组中的属性值进行过滤?

Rag*_*hav 3 angular

我有一个输入文本,该区域如下所示:

<input type="text" [(ngModel)]="areaSearch">
Run Code Online (Sandbox Code Playgroud)

并且,我有一个列表,根据输入的area_name属性区域进行过滤

<ul *ngIf="areaSearch">
    <li *ngFor="let area of areaList | filter : {area_name: areaSearch} ">
        ...
    </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我得到的错误就像The pipe 'filter' could not be found.任何人都可以帮我解决这个问题吗?

Saj*_*ran 9

Angular没有命名的概念filter,相反你应该创建custom pipe如下,

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'filterByArea'})
export class FilterByStatusPipe implements PipeTransform {

    transform(areaList : any, areaname: string): any[] {
        if (areaList) {
            return areaList.filter((listing: any) => listing.area_name === areaname);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并使用如下,

<ul *ngIf="areaSearch">
    <li *ngFor="let area of areaList | filterByArea:areaSearch  ">
        ...
    </li>
</ul>
Run Code Online (Sandbox Code Playgroud)


Bee*_*ice 5

我将filteredAreaList在组件中定义为只读:

// this goes in the component
get filteredAreaList() {
    return this.areaList.filter(v => v.area_name === this.areaSearch)
}
Run Code Online (Sandbox Code Playgroud)

这将确保filteredAreaList仅具有areaListarea_name属性与当前属性匹配的那些元素areaSearch

然后在模板中进行迭代 filteredAreaList

<ul *ngIf="areaSearch">
    <li *ngFor="let area of filteredAreaList ">
        ...
    </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

这种方法的一个好处是逻辑不包含在模板中,并且易于扩展(例如:如果将来显示的列表取决于其他组件属性)。我也喜欢Sajeetharan的管道解决方案。

更新时间:2019-05-17

自从我写出答案以来,我已经有近2年的Angular了,我对阅读我的和Sajeetharan的可接受的答复有一个新的观点。我的解决方案的开销较少;它也更容易实现;步骤更少-无需创建管道,无需在模块中声明它,确保组件的模块也可以访问它,等等。但是Sajeetharan的解决方案将运行得更快,特别areaList是在数组较大的情况下,因为默认情况下,管道逻辑为仅在输入更改时运行。

这意味着实际上,一旦用户输入了区域名称,过滤器将只执行一次并完成,而使用我的解决方案,filteredAreaListgetter将执行每个更改检测周期。如果您只有几十个区域,那么差异是微不足道的,但是如果您拥有非常大的区域,则差异很重要。