显然,Angular 2将像在Angular1中一样使用管道而不是过滤器,并结合ng-for来过滤结果,尽管实现看起来仍然很模糊,没有明确的文档。
也就是说,我想要达到的目标可以从以下角度来看待
<div *ng-for="#item of itemsList" *ng-if="conditon(item)"></div>
如何实现这样使用管道?
显然,Angular 2将像在Angular1中一样使用管道而不是过滤器,并结合ng-for来过滤结果,尽管实现看起来仍然很模糊,没有明确的文档。
也就是说,我想要达到的目标可以从以下角度来看待
<div *ng-for="#item of itemsList" *ng-if="conditon(item)"></div>
如何实现这样使用管道?
当前回答
我创建了下面的管道,用于从列表中获取所需的项。
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>
其他回答
基本上,你写了一个管道,然后在*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中没有内置过滤器管道是有原因的。
我知道这是一个老问题,但是,我认为提供另一种解决方案可能会有所帮助。
相当于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")但不想用另一个元素包装它们时很有用。
简化方式(由于性能问题,仅用于小型数组。在大型数组中,你必须通过代码手动创建过滤器):
见: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>
如果使用变量作为第二个参数,不要使用引号。
你也可以使用以下语句:
<template ngFor let-item [ngForOf]="itemsList">
<div *ng-if="conditon(item)"></div>
</template>
这将只显示div,如果您的项目符合条件
更多信息请参阅angular文档 如果你还需要索引,请使用以下方法:
<template ngFor let-item [ngForOf]="itemsList" let-i="index">
<div *ng-if="conditon(item, i)"></div>
</template>
这是我不久前创建的一个例子,并在博客上发表过,其中包括一个工作的扑通。它提供了一个过滤管道,可以过滤任何对象列表。基本上你只需要在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/