显然,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>
如何实现这样使用管道?
当前回答
我正在寻找一些东西,让一个过滤器传递一个对象,然后我可以使用它像多过滤器:
我做了这个美容方案:
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">...
其他回答
我知道这是一个老问题,但是,我认为提供另一种解决方案可能会有所帮助。
相当于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")但不想用另一个元素包装它们时很有用。
这是我在没有使用管道的情况下实现的。
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;
}
}
管子是最好的方法。但低于1也可以。
<div *ng-for="#item of itemsList">
<ng-container *ng-if="conditon(item)">
// my code
</ng-container>
</div>
这是我的代码:
import {Pipe, PipeTransform, Injectable} from '@angular/core';
@Pipe({
name: 'filter'
})
@Injectable()
export class FilterPipe implements PipeTransform {
transform(items: any[], field : string, value): any[] {
if (!items) return [];
if (!value || value.length === 0) return items;
return items.filter(it =>
it[field] === value);
}
}
示例:
LIST = [{id:1,name:'abc'},{id:2,name:'cba'}];
FilterValue = 1;
<span *ngFor="let listItem of LIST | filter : 'id' : FilterValue">
{{listItem .name}}
</span>
第一步是在组件中使用@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>