显然,Angular 2将像在Angular1中一样使用管道而不是过滤器,并结合ng-for来过滤结果,尽管实现看起来仍然很模糊,没有明确的文档。

也就是说,我想要达到的目标可以从以下角度来看待

<div *ng-for="#item of itemsList" *ng-if="conditon(item)"></div>

如何实现这样使用管道?


当前回答

这是我不久前创建的一个例子,并在博客上发表过,其中包括一个工作的扑通。它提供了一个过滤管道,可以过滤任何对象列表。基本上你只需要在ngFor规范中指定属性和值{key:value}。

这与@NateMay的回复没有太大不同,只是我比较详细地解释了它。

在我的例子中,我过滤了一个无序列表的一些文本(filterText),用户输入针对对象的“label”属性在我的数组中使用这种标记:

<ul>
  <li *ngFor="let item of _items | filter:{label: filterText}">{{ item.label }}</li>
</ul>

https://long2know.com/2016/11/angular2-filter-pipes/

其他回答

我喜欢用于特定于应用程序的过滤器的另一种方法是在组件上使用自定义只读属性,这允许您比使用自定义管道(IMHO)更清晰地封装过滤逻辑。

例如,如果我想绑定到albumList并过滤searchText:

searchText: "";
albumList: Album[] = [];

get filteredAlbumList() {
    if (this.config.searchText && this.config.searchText.length > 1) {
      var lsearchText = this.config.searchText.toLowerCase();
      return this.albumList.filter((a) =>
        a.Title.toLowerCase().includes(lsearchText) ||
        a.Artist.ArtistName.toLowerCase().includes(lsearchText)
      );
    }
    return this.albumList;
}

要在HTML中绑定,你可以绑定到只读属性:

<a class="list-group-item"
       *ngFor="let album of filteredAlbumList">
</a>

我发现对于特定于应用程序的专用过滤器,这比管道工作得更好,因为它保持了与组件过滤器相关的逻辑。

管道对于全局可重用过滤器工作得更好。

这是你的数组

products: any = [
        {
            "name": "John-Cena",
                    },
        {
            "name": "Brock-Lensar",

        }
    ];

这是你的ngFor循环 过滤者:

<input type="text" [(ngModel)]='filterText' />
    <ul *ngFor='let product of filterProduct'>
      <li>{{product.name }}</li>
    </ul>

这里我使用的是产品的filterProduct instant,因为我想保留原始数据。 这里model _filterText用作输入框。当有任何变化setter函数将调用。 在setFilterText调用performProduct时,它只返回与输入匹配的结果。我用小写表示不区分大小写。

filterProduct = this.products;
_filterText : string;
    get filterText() : string {
        return this._filterText;
    }

    set filterText(value : string) {
        this._filterText = value;
        this.filterProduct = this._filterText ? this.performProduct(this._filterText) : this.products;

    } 

    performProduct(value : string ) : any {
            value = value.toLocaleLowerCase();
            return this.products.filter(( products : any ) => 
                products.name.toLocaleLowerCase().indexOf(value) !== -1);
        }

我使用了一个动态过滤管道

源数据:

items = [{foo: 'hello world'}, {foo: 'lorem ipsum'}, {foo: 'foo bar'}];

在模板中,你可以在任意对象attr中动态设置过滤器:

<li *ngFor="let item of items | filter:{foo:'bar'}">

管:

  import { Pipe, PipeTransform } from '@angular/core';

  @Pipe({
    name: 'filter',
  })
  export class FilterPipe implements PipeTransform {
    transform(items: any[], filter: Record<string, any>): any {
      if (!items || !filter) {
        return items;
      }

      const key = Object.keys(filter)[0];
      const value = filter[key];

      return items.filter((e) => e[key].indexOf(value) !== -1);
    }
  }

不要忘记在app.module.ts声明中注册管道

很多人都有很好的方法,但这里的目标是通用的和定义的数组管道,它在与*ngFor相关的所有情况下都是非常可重用的。

ts(不要忘记将其添加到模块的声明数组中)

import { PipeTransform, Pipe } from '@angular/core';

@Pipe({
    name: 'callback',
    pure: false
})
export class CallbackPipe implements PipeTransform {
    transform(items: any[], callback: (item: any) => boolean): any {
        if (!items || !callback) {
            return items;
        }
        return items.filter(item => callback(item));
    }
}

然后在您的组件中,您需要实现一个具有以下signature (item: any) => boolean的方法,例如,在我的示例中,我将其称为filterUser,用于过滤大于18岁的用户的年龄。

您的组件

@Component({
  ....
})
export class UsersComponent {
  filterUser(user: IUser) {
    return !user.age >= 18
  }
}

最后,你的html代码看起来是这样的:

HTML

<li *ngFor="let user of users | callback: filterUser">{{user.name}}</li>

正如您所看到的,这个Pipe对于所有需要通过回调筛选的数组(如项目)都是相当通用的。在我的例子中,我发现它对于*ngFor之类的场景非常有用。

希望这能有所帮助!!

codematrix

在谷歌搜索之后,我发现了ng2-search-filter。In将获取您的对象并对所有对象属性应用搜索项以查找匹配项。