显然,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>
如何实现这样使用管道?
当前回答
简化方式(由于性能问题,仅用于小型数组。在大型数组中,你必须通过代码手动创建过滤器):
见: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>
如果使用变量作为第二个参数,不要使用引号。
其他回答
简化方式(由于性能问题,仅用于小型数组。在大型数组中,你必须通过代码手动创建过滤器):
见: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>
如果使用变量作为第二个参数,不要使用引号。
我根据这里和其他地方的答案创建了一个活塞。
此外,我必须添加一个<input>的@Input, @ViewChild和ElementRef,并创建和订阅()到它的一个可观察对象。
Angular2搜索过滤器:PLUNKR(更新:plunker不再工作)
我喜欢用于特定于应用程序的过滤器的另一种方法是在组件上使用自定义只读属性,这允许您比使用自定义管道(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>
我发现对于特定于应用程序的专用过滤器,这比管道工作得更好,因为它保持了与组件过滤器相关的逻辑。
管道对于全局可重用过滤器工作得更好。
基本上,你写了一个管道,然后在*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中没有内置过滤器管道是有原因的。
第一步是在组件中使用@Pipe创建Filter。ts文件:
your.component.ts
import { Component, Pipe, PipeTransform, Injectable } from '@angular/core';
import { Person} from "yourPath";
@Pipe({
name: 'searchfilter'
})
@Injectable()
export class SearchFilterPipe implements PipeTransform {
transform(items: Person[], value: string): any[] {
if (!items || !value) {
return items;
}
console.log("your search token = "+value);
return items.filter(e => e.firstName.toLowerCase().includes(value.toLocaleLowerCase()));
}
}
@Component({
....
persons;
ngOnInit() {
//inicial persons arrays
}
})
和Person对象的数据结构:
person.ts
export class Person{
constructor(
public firstName: string,
public lastName: string
) { }
}
在你的html文件视图中:
your.component.html
<input class="form-control" placeholder="Search" id="search" type="text" [(ngModel)]="searchText"/>
<table class="table table-striped table-hover">
<colgroup>
<col span="1" style="width: 50%;">
<col span="1" style="width: 50%;">
</colgroup>
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let person of persons | searchfilter:searchText">
<td>{{person.firstName}}</td>
<td>{{person.lastName}}</td>
</tr>
</tbody>
</table>