我有这个项目列表在我的JSON中,我只想搜索项目名称而忽略其他字段。我现在的问题是它还搜索其他字段。如何只在我的管道中使用项目名称进行搜索而不影响它的其他字段。这是我在下面所做的。
JSON
{
"token": "ejsk0e",
"projects": [
{
"id": 5,
"name": "Store",
"description": "Small",
"organization_id": 1,
"created_at": "2017-10-29 10:31:50",
"updated_at": "2017-11-14 06:27:03",
"material_projects": [
{
"id": 18,
"material_id": 40,
"project_id": 5,
"quantity": 10,
"unit": "pcs",
"created_at": "2017-11-02 09:57:14",
"updated_at": "2017-11-02 09:57:14",
"material": {
"id": 40,
"sku": "ACWNAIL",
"name": "Banana",
"created_at": "2017-10-26 03:19:54",
"updated_at": "2017-10-26 03:23:21"
},
"categories": [
{
"id": 8,
"name": "Fruits",
"created_at": "2017-10-26 07:36:48",
"updated_at": "2017-11-10 02:06:07",
"pivot": {
"material_proj_id": 18,
"category_id": 8
}
}
],
"material_name": "Banana",
"material_sku": "ACWNAIL",
"category_name": "Fruits"
}
]
}
TS
getAllProjects() {
this.subscription = this.projectsService.getAll()
.subscribe(
(data:any) => {
this.projects = data.projects;
},
error => {
console.log(error);
});
}
HTML
<div class="container-fluid">
<input placeholder="Search..."" type="text" [(ngModel)]="searchProj">
<div class="row" *ngFor="let project of projects | search : searchProj">
<div class="card-block">
<h2 class="proj-name">{{ project.name }}</h2>
</div>
</div>
</div>
PIPE.ts
export class SearchPipe implements PipeTransform {
transform(items: any, term: any): any {
if (term === undefined) return items;
return items.filter(function(item) {
for(let property in item){
if (item[property] === null){
continue;
}
if(item[property].toString().toLowerCase().includes(term.toLowerCase())){
return true;
}
}
return false;
});
}
}
答案 0 :(得分:0)
解决问题的方法是将属性作为变量提供给管道:
transform(items: any, term: any, prop: string): any {
if (!term || !prop) return items;
return items.filter((item) =>
item[prop].toString().toLowerCase().includes(term.toLowerCase()));
}
<div class="row" *ngFor="let project of projects | search : searchProj : 'name'">
...无论其
您永远不应该在管道转换中执行排序和过滤等操作。管道转换触发每个单独的更改检测周期,这是非常频繁的,这导致在每个更改检测周期重新应用排序和过滤,无论它们是否需要,这导致极差的应用程序性能。事实上,angularJS包括一个过滤管,但由于广泛滥用导致应用程序性能不佳而被删除。更好的方法是建立一个逻辑,当你需要自己触发排序或过滤而不是依靠变化检测来为你做。
使用反应式表单而不是ngModel会更容易,因此我的示例将使用它。
TS:
this.projects$ = this.projectsService.getAll();
this.searchProj = new FormControl('');
this.search$ = this.searchProj.valueChanges.startWith('').debounce(300).distinctUntilChanged();
this.filteredProjects$= Observable.combineLatest(this.projects$, this.search$)
.map(([projects, searchTerm]) => (searchTerm) ? projects.filter(p => p.name.toString().toLowerCase().includes(searchTerm.toLowerCase()) : projects);
然后你的html:
<div class="container-fluid">
<input placeholder="Search..."" type="text" [formControl]="searchProj">
<div class="row" *ngFor="let project of filteredProjects$ | async">
<div class="card-block">
<h2 class="proj-name">{{ project.name }}</h2>
</div>
</div>
</div>
引导您完成此代码,首先存储用于在可观察项中检索项目的服务方法,然后为搜索项创建表单控件,然后将其值更改方法存储在observable中,首先告诉它从一个空值开始,然后去除它,只获取distnct值(这是一个小的优化,这样如果用户快速键入你实际上只搜索每两个字符,不研究他们是否快速输入和删除一个字符)。然后将这两个组合在一个新的observable中,并将它们一起映射到过滤器函数中,以便每次项目更改时都会过滤项目。
至于你原来的问题......现在这是一个非因素,因为你没有使用通用的东西作为管道,你可以只显式过滤name属性,或者你可以只采取上面的转换函数如果经常使用过滤逻辑,请在地图运算符中使用它。