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

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

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

如何实现这样使用管道?


当前回答

我知道这是一个老问题,但是,我认为提供另一种解决方案可能会有所帮助。

相当于AngularJS的这个

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

在Angular 2+中,你不能在同一个元素上使用*ngFor和*ngIf,所以它会如下所示:

<div *ngFor="let item of itemsList">
     <div *ngIf="conditon(item)">
     </div>
</div>

如果你不能作为内部容器使用ng-container代替。 ng-container在你想有条件地在你的应用程序中添加一组元素(例如使用*ngIf="foo")但不想用另一个元素包装它们时很有用。

其他回答

基本上,你写了一个管道,然后在*ngFor指令中使用。

在你的组件中:

filterargs = {title: 'hello'};
items = [{title: 'hello world'}, {title: 'hello kitty'}, {title: 'foo bar'}];

在你的模板中,你可以将字符串,数字或对象传递给你的管道来过滤:

<li *ngFor="let item of items | myfilter:filterargs">

在你的烟斗里

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

@Pipe({
    name: 'myfilter',
    pure: false
})
export class MyFilterPipe implements PipeTransform {
    transform(items: any[], filter: Object): any {
        if (!items || !filter) {
            return items;
        }
        // filter items array, items which match and return true will be
        // kept, false will be filtered out
        return items.filter(item => item.title.indexOf(filter.title) !== -1);
    }
}

记住在app.module.ts中注册你的管道;你不再需要在@Component中注册管道

import { MyFilterPipe } from './shared/pipes/my-filter.pipe';

@NgModule({
    imports: [
        ..
    ],
    declarations: [
        MyFilterPipe,
    ],
    providers: [
        ..
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

下面是一个Plunker,它演示了使用自定义过滤管道和内置切片管道来限制结果。

请注意(正如一些评论员指出的那样),Angular中没有内置过滤器管道是有原因的。

我创建了下面的管道,用于从列表中获取所需的项。

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

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {

  transform(items: any[], filter: string): any {
    if(!items || !filter) {
      return items;
    }
    // To search values only of "name" variable of your object(item)
    //return items.filter(item => item.name.toLowerCase().indexOf(filter.toLowerCase()) !== -1);

    // To search in values of every variable of your object(item)
    return items.filter(item => JSON.stringify(item).toLowerCase().indexOf(filter.toLowerCase()) !== -1);
  }

}

小写转换只是为了匹配不区分大小写的方式。 你可以在你的视图中这样使用它:-

<div>
  <input type="text" placeholder="Search reward" [(ngModel)]="searchTerm">
</div>
<div>
  <ul>
    <li *ngFor="let reward of rewardList | filter:searchTerm">
      <div>
        <img [src]="reward.imageUrl"/>
        <p>{{reward.name}}</p>
      </div>
    </li>
  </ul>
</div>

对于这个需求,我实现并发布了一个通用组件。看到

https://www.npmjs.com/package/w-ng5

在使用此组件之前,使用npm安装此包:

npm install w-ng5 --save

之后,在app.module中导入模块

...
import { PipesModule } from 'w-ng5';

下一步,在app.module中添加declare部分:

imports: [
  PipesModule,
  ...
]

样本用

过滤简单字符串

<input type="text"  [(ngModel)]="filtroString">
<ul>
  <li *ngFor="let s of getStrings() | filter:filtroString">
    {{s}}
  </li>
</ul>

在级别2中过滤复杂字符串字段“Value”

<input type="text"  [(ngModel)]="search">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.valor2', value: search}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

过滤复杂字符串-中间字段- 1级中的“值”

<input type="text"  [(ngModel)]="search3">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.valor1', value: search3}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

过滤复杂数组的简单字段“Nome”级别为0

<input type="text"  [(ngModel)]="search2">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'nome', value: search2}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

在树字段中过滤-在第2级中字段'Valor'或在第1级中字段'Valor'或在第0级中字段'Nome'

<input type="text"  [(ngModel)]="search5">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.valor2', value: search5}, {field:'n1.valor1', value: search5}, {field:'nome', value: search5}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

过滤不存在的字段- 'Valor'在不存在的级别3

<input type="text"  [(ngModel)]="search4">
<ul>
  <li *ngFor="let s of getComplexTypesExtends() | filter:[{field:'n1.n2.n3.valor3', value: search4}]">
    {{s.nome}} - {{s.idade}} - {{s.n1.valor1}} - {{s.n1.n2.valor2}}
  </li>
</ul>

该组件具有无限属性级别…

我不确定它是什么时候进来的,但他们已经做了切片管,可以做到这一点。它也有很好的记录。

https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html

<p *ngFor="let feature of content?.keyFeatures | slice:1:5">
   {{ feature.description }}
</p>

我正在寻找一些东西,让一个过滤器传递一个对象,然后我可以使用它像多过滤器:

我做了这个美容方案:

filter.pipe.ts

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

@Pipe({
  name: 'filterx',
  pure: false
})
export class FilterPipe implements PipeTransform {
 transform(items: any, filter: any, isAnd: boolean): any {
  let filterx=JSON.parse(JSON.stringify(filter));
  for (var prop in filterx) {
    if (Object.prototype.hasOwnProperty.call(filterx, prop)) {
       if(filterx[prop]=='')
       {
         delete filterx[prop];
       }
    }
 }
if (!items || !filterx) {
  return items;
}

return items.filter(function(obj) {
  return Object.keys(filterx).every(function(c) {
    return obj[c].toLowerCase().indexOf(filterx[c].toLowerCase()) !== -1
  });
  });
  }
}

component.ts

slotFilter:any={start:'',practitionerCodeDisplay:'',practitionerName:''};

componet.html

             <tr>
                <th class="text-center">  <input type="text" [(ngModel)]="slotFilter.start"></th>
                <th class="text-center"><input type="text" [(ngModel)]="slotFilter.practitionerCodeDisplay"></th>
                <th class="text-left"><input type="text" [(ngModel)]="slotFilter.practitionerName"></th>
                <th></th>
              </tr>


 <tbody *ngFor="let item of practionerRoleList | filterx: slotFilter">...