如何根据对象 属性 字符串过滤“ngFor”循环内的项目
How to filter items inside “ngFor” loop, based on object property string
我需要通过更改下拉列表中的类别来过滤 ngFor
循环中的项目。因此,当从列表中选择特定类别时,它应该只列出包含相同类别的项目。
HTML 模板:
<select>
<option *ngFor="let model of models">{{model.category}}</option>
</select>
<ul class="models">
<li *ngFor="let model of models" (click)="gotoDetail(model)">
<img [src]="model.image"/>
{{model.name}},{{model.category}}
</li>
</ul>
项目数组:
export var MODELS: Model[] = [
{ id: 1,
name: 'Model 1',
image: 'img1',
category: 'Cat1',
},
{ id: 2,
name: 'Model 2',
image: 'img2',
category: 'Cat3',
},
{ id: 3,
name: 'Model 3',
image: 'img3',
category: 'Cat1',
},
{ id: 4,
name: 'Model 4',
image: 'img4',
category: 'Cat4',
},
...
];
此外,下拉列表包含重复的类别名称。它有必要只列出唯一的类别(字符串)。
我知道创建自定义管道是执行此操作的正确方法,但我不知道如何编写。
这是一个示例管道:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'matchesCategory'
})
export class MathcesCategoryPipe implements PipeTransform {
transform(items: Array<any>, category: string): Array<any> {
return items.filter(item => item.category === category);
}
}
使用方法:
<li *ngFor="let model; of models | matchesCategory:model.category" (click)="gotoDetail(model)">
===== 对于 plunkr 示例 ====
您需要 select 更改以反映在某些变量中
首先在你的class中定义一个成员:
selectedCategory: string;
然后更新您的模板:
<select (change)="selectedCategory = $event.target.value">
<option *ngFor="let model of models ">{{model.category}}</option>
</select>
最后,使用管道:
<li *ngFor="let model; of models | matchesCategory:selectedCategory" (click)="gotoDetail(model)">
==== 看到傻瓜后的评论====
我注意到你使用了 promise。 Angular2 更面向 rxjs。因此,我首先要更改的是您的服务,替换为:
getModels(): Promise<Model[]> {
return Promise.resolve(MODELS);
}
至:
getModels(): Observable<Array<Model>> {
return Promise.resolve(MODELS);
}
和
getModels(id: number): Observable<Model> {
return getModels().map(models => models.find(model.id === id);
}
然后在你的 ModelsComponent
models$: Observable<Array<Model>> = svc.getModels();
uniqueCategories$: Observable<Array<Model>> = this.models$
.map(models => models.map(model => model.category)
.map(categories => Array.from(new Set(categories)));
您的选项将变为:
<option *ngFor="let category; of uniqueCategories$ | async">{{model.category}}</option>
和您的列表:
<li *ngFor="let model; of models$ | async | matchesCategory:selectedCategory" (click)="gotoDetail(model)">
这是一个非常草率的解决方案,因为您有很多重复项并且您一直在查询服务。以此为起点,只查询一次服务,然后从得到的结果中推导出具体的值。
如果您想保留代码,只需实现一个 UniqueValuesPipe,它的转换将获取单个参数并使用 Array.from(new Set(...))
将其过滤到 return 个独特类别。不过,您需要先将其映射到字符串(类别)。
我需要通过更改下拉列表中的类别来过滤 ngFor
循环中的项目。因此,当从列表中选择特定类别时,它应该只列出包含相同类别的项目。
HTML 模板:
<select>
<option *ngFor="let model of models">{{model.category}}</option>
</select>
<ul class="models">
<li *ngFor="let model of models" (click)="gotoDetail(model)">
<img [src]="model.image"/>
{{model.name}},{{model.category}}
</li>
</ul>
项目数组:
export var MODELS: Model[] = [
{ id: 1,
name: 'Model 1',
image: 'img1',
category: 'Cat1',
},
{ id: 2,
name: 'Model 2',
image: 'img2',
category: 'Cat3',
},
{ id: 3,
name: 'Model 3',
image: 'img3',
category: 'Cat1',
},
{ id: 4,
name: 'Model 4',
image: 'img4',
category: 'Cat4',
},
...
];
此外,下拉列表包含重复的类别名称。它有必要只列出唯一的类别(字符串)。
我知道创建自定义管道是执行此操作的正确方法,但我不知道如何编写。
这是一个示例管道:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'matchesCategory'
})
export class MathcesCategoryPipe implements PipeTransform {
transform(items: Array<any>, category: string): Array<any> {
return items.filter(item => item.category === category);
}
}
使用方法:
<li *ngFor="let model; of models | matchesCategory:model.category" (click)="gotoDetail(model)">
===== 对于 plunkr 示例 ====
您需要 select 更改以反映在某些变量中
首先在你的class中定义一个成员:
selectedCategory: string;
然后更新您的模板:
<select (change)="selectedCategory = $event.target.value">
<option *ngFor="let model of models ">{{model.category}}</option>
</select>
最后,使用管道:
<li *ngFor="let model; of models | matchesCategory:selectedCategory" (click)="gotoDetail(model)">
==== 看到傻瓜后的评论====
我注意到你使用了 promise。 Angular2 更面向 rxjs。因此,我首先要更改的是您的服务,替换为:
getModels(): Promise<Model[]> {
return Promise.resolve(MODELS);
}
至:
getModels(): Observable<Array<Model>> {
return Promise.resolve(MODELS);
}
和
getModels(id: number): Observable<Model> {
return getModels().map(models => models.find(model.id === id);
}
然后在你的 ModelsComponent
models$: Observable<Array<Model>> = svc.getModels();
uniqueCategories$: Observable<Array<Model>> = this.models$
.map(models => models.map(model => model.category)
.map(categories => Array.from(new Set(categories)));
您的选项将变为:
<option *ngFor="let category; of uniqueCategories$ | async">{{model.category}}</option>
和您的列表:
<li *ngFor="let model; of models$ | async | matchesCategory:selectedCategory" (click)="gotoDetail(model)">
这是一个非常草率的解决方案,因为您有很多重复项并且您一直在查询服务。以此为起点,只查询一次服务,然后从得到的结果中推导出具体的值。
如果您想保留代码,只需实现一个 UniqueValuesPipe,它的转换将获取单个参数并使用 Array.from(new Set(...))
将其过滤到 return 个独特类别。不过,您需要先将其映射到字符串(类别)。