2在对象中的"数组值"上选择过滤器



我有以下数据对象:

goods = [
{ name: 'Canon', title: 'Canon EOS 5D Mark III Body', tags: ['tag1','tag2','tag3']},
{ name: 'Nikon', title: 'Nikon D3100', tags: ['tag1','tag4','tag5']},
{ name: 'Sony', title: 'Sony CX700', tags: ['tag2','tag3','tag6']},
{ name: 'Fujifilm', title: 'Fujifilm XT20',tags: ['tag1','tag4','tag5']},       
{ name: 'Sony', title: 'Sony CX500', tags: ['tag3','tag4','tag5']},
{ name: 'Nikon', title: 'Nikon D750', tags: ['tag1','tag5','tag6']},
];

以及一个包含2个选择框的html页面。

<select [(ngModel)]="selectedTag1" (change)="valueSelected1()">
<option  *ngFor="let item of tagName">{{ item }}</option>
</select>
<select [(ngModel)]="selectedTag2" (change)="valueSelected2()">
<option  *ngFor="let item of tagName">{{ item }}</option>
</select>
<div *ngFor="let item of goods">
<app-goods [goodsData]="item"></app-goods>
</div>

在我的ts文件中,我想过滤selectedTag1、selectedTag2或两者的标签数组。我不知道如何过滤数组(我需要循环它吗?(,也不知道如何组合这两个过滤器(我需要RXJS的combineLatest吗?(。到目前为止,我有以下

ngOnInit() {
this.tagName = this.dropdownService.brandName;
this.goods = this.goodsService.goods;
};
public valueSelected1() {
this.goods = this.goodsService.goods.filter(item => item.tags[0] === this.selectedTag1);
console.log(this.selectedTag1);
}
public valueSelected2() {
this.goods = this.goodsService.goods.filter(item => item.tags[0] === this.selectedTag1);
console.log(this.selectedTag2);
}

我想我需要循环遍历这里的数组item.tags[0],但不确定最好的方法,然后进行组合Latest。。也许不是?我创建了一个stackBlitz

您可以通过多种方式之一来实现这一点:

  1. 使用吸气剂
get goodsFiltered(): any[] {
return this.goods?.filter(({ tags }) => tags.indexOf(this.selectedTag1) !== -1 && tags.indexOf(this.selectedTag2) !== -1) ?? [];
}
  1. 使用自定义管道(imho的最佳方式(
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'filteredGoods' })
export class FilteredGoodsPipe implements PipeTransform {
transform(goods: any[], { tag1, tag2 }): any[] {
return goods.filter(({ tags }) => tags.indexOf(tag1) !== -1 && tags.indexOf(tag2) !== -1);
}
}
<div *ngFor="let item of goods | filteredGoods: { tag1: selectedTag1, tag2: selectedTag2 }">
<app-goods [goodsData]="item"></app-goods>
</div>
  1. 直接在change事件回调中:
public valueSelected1() {
this.goods = this.goods.filter(({ tags }) => tags.indexOf(this.selectedTag1) !== -1 && tags.indexOf(this.selectedTag2) !== -1);
}
public valueSelected2() {
this.goods = this.goods.filter(({ tags }) => tags.indexOf(this.selectedTag1) !== -1 && tags.indexOf(this.selectedTag2) !== -1);
}

希望这有帮助:(

编辑:我不知道东西有什么类型,但如果this.goodsService.goodsObservable,你应该使用管道过滤运算符:

ngOnInit() {
this.tagName = this.dropdownService.brandName;
this.goods = this.goodsService.goods.pipe(
filter(({ tags }) => tags.indexOf(this.selectedTag1) !== -1 && tags.indexOf(this.selectedTag2) !== -1)
);
}

您可以使用一些方法来检查数组是否包含some值:

public valueSelected1() {
this.goods = this.goodsService.goods.filter(item => 
item.tags.some(s => s == this.selectedTag1));
console.log(this.selectedTag1);
}
public valueSelected2() {
this.goods = this.goodsService.goods.filter(item => 
item.tags.some( s => s == this.selectedTag1));
console.log(this.selectedTag2);
}

请参阅workstackblitz示例。

使用以下方法,而不是valueSelected1valueSelected2

public onChangeSelection() {
this.goods = this.goodsService.goods.filter(item => 
(this.selectedTag1 && item.tags.includes(this.selectedTag1)) || 
(this.selectedTag1 && item.tags.includes(this.selectedTag1)));
console.log(this.selectedTag1);
}

我使用了includes语法,因为检查selectedTag是否存在于数组中,并且您检查了数组的第一个索引,我认为这是错误的

最新更新