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

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

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

如何实现这样使用管道?


当前回答

这是我在没有使用管道的情况下实现的。

component.html

<div *ngFor="let item of filter(itemsList)">

component.ts

@Component({
....
})
export class YourComponent {
  filter(itemList: yourItemType[]): yourItemType[] {
    let result: yourItemType[] = [];
    //your filter logic here
    ...
    ...
    return result;
  }
}

其他回答

你可以这样做:

<ng-container *ngFor="item in items">
    <div *ngIf="conditon(item)">{{ item.value }}</div>
</ng-container>

or

<div *ngFor="item in items">
  <ng-container *ngIf="conditon(item)">{{ item.value }}</ng-container>
</div>

简化方式(由于性能问题,仅用于小型数组。在大型数组中,你必须通过代码手动创建过滤器):

见:https://angular.io/guide/pipes appendix-no-filterpipe-or-orderbypipe

@Pipe({
    name: 'filter'
})
@Injectable()
export class FilterPipe implements PipeTransform {
    transform(items: any[], field : string, value : string): any[] {  
      if (!items) return [];
      if (!value || value.length == 0) return items;
      return items.filter(it => 
      it[field].toLowerCase().indexOf(value.toLowerCase()) !=-1);
    }
}

用法:

<li *ngFor="let it of its | filter : 'name' : 'value or variable'">{{it}}</li>

如果使用变量作为第二个参数,不要使用引号。

这是你的数组

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);
        }

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

相当于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中没有内置过滤器管道是有原因的。