显然,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>
如何实现这样使用管道?
当前回答
很多人都有很好的方法,但这里的目标是通用的和定义的数组管道,它在与*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
其他回答
我根据这里和其他地方的答案创建了一个活塞。
此外,我必须添加一个<input>的@Input, @ViewChild和ElementRef,并创建和订阅()到它的一个可观察对象。
Angular2搜索过滤器:PLUNKR(更新:plunker不再工作)
简化方式(由于性能问题,仅用于小型数组。在大型数组中,你必须通过代码手动创建过滤器):
见: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);
}
管子是最好的方法。但低于1也可以。
<div *ng-for="#item of itemsList">
<ng-container *ng-if="conditon(item)">
// my code
</ng-container>
</div>
理想情况下,您应该为此创建angualr 2管道。但是你可以做这个魔术。
<ng-container *ngFor="item in itemsList">
<div*ngIf="conditon(item)">{{item}}</div>
</ng-container>