自定义管道产品过滤器?
Custom Pipe product filter?
所以我想要实现的是能够在 NgFor 上切换多个过滤器,每次打开或关闭过滤器时它都会更新。
我有这个烟斗:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterProducts'
})
export class FilterProducts implements PipeTransform {
transform(products: any[], args: {[field : string] : string[]}): any[] {
if (!products) return [];
if (!args) return products;
return products.filter((pr: any) => {
for(let field in args) {
if(args[field ].indexOf(pr[field]) === -1) {
return false;
}
}
return true;
});
}
}
在我的 app.module.ts 我有(为简洁起见减少):
import { FilterProducts } from '../pages/products/productsFilter.pipe';
@NgModule({
declarations: [
FilterProducts
]
})
在我的产品组件中我有:
public filterArgs : {[field : string] : string[]} = {};
constructor() { }
addBrandFilter(brands: string[]) {
this.addFilter('brand', brands);
}
addFilter(field: string, values: string[]): void {
this.filterArgs[field] = values;
}
然后在我的 NgFor 上有(为简洁起见减少):
*ngFor="let product of products | filterProducts: filterArgs;"
<li class="search-filters__item" (click)="addBrandFilter(['Brand Name'])">Brand Name</li>
我使用模板进行过滤设置的方式包括价格、品牌和类型。其中有一些用户可以单击的按钮,例如价格为 0-50 或 50-100 等。理想情况下,我希望能够同时应用这些按钮。因此将选择 0-50 和 50-100 并适当过滤 ngFor。
有谁能给我一些关于如何实现这一点的建议吗?我到处搜索,只能根据搜索框或下拉列表找到管道。
编辑
我现在更新了这个以反映@PierreDuc 给我的帮助。我现在正在努力将相关过滤器传递给 filterArgs。
编辑 2
感谢@PierreDuc,我现在再次更新了这个以反映进度。目前 ngFor 不过滤通过(点击)传递的品牌名称。
提前致谢。
您声明您的 filterArgs
是一个字符串数组。在这种情况下,您应该将过滤器更改为:
@Pipe({
name: 'filterProducts'
})
export class FilterProducts implements PipeTransform {
transform(products: any[], field : string, value : string[]): any[] {
if (!products) return [];
if (!value) return products;
return products.filter((pr: any) => {
return value.indexOf(pr[field]) > -1
});
}
}
你可以这样称呼:
*ngFor="let product of products | filterProducts: 'name' : ['cup', 'tea']"
这将 return 所有名称为 cup
或 tea
的产品。如果适用于您,请注意区分大小写
要过滤多个属性,您最好将 {field : values}
对象发送到管道:
要使用您的评论:
let filterArgs : {[field : string] : string[]} = {
name : ['brand', 'otherbrand'],
type : ['A', 'B']
};
然后在你的管道中使用这个:
*ngFor="let product of products | filterProducts: filterArgs"
你的管道变成这样:
@Pipe({
name: 'filterProducts'
})
export class FilterProducts implements PipeTransform {
transform(products: any[], args: {[field : string] : string[]}): any[] {
if (!products) return [];
if (!args) return products;
return products.filter((pr: any) => {
for(let field in args) {
if(args[field ].indexOf(pr[field]) === -1) {
return false;
}
}
return true;
});
}
}
对于价格评估,我建议您构建一个不同的管道,您可以在其中给出最大和最小设置并将其与产品价格进行比较
更新
作为对代码的更新,您应该在构造函数中分配 class 属性,而不是局部变量。 filterArds 是一个对象,而不是数组。所以不需要像你那样初始化它:
public filterArgs : {[field : string] : string[]} = {};
constructor() { }
addBrandFilter(brands: string[]) {
this.addFilter('brand', brands);
}
addFilter(field: string, values: string[]): void {
this.filterArgs[field] = values;
}
所以我想要实现的是能够在 NgFor 上切换多个过滤器,每次打开或关闭过滤器时它都会更新。
我有这个烟斗:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterProducts'
})
export class FilterProducts implements PipeTransform {
transform(products: any[], args: {[field : string] : string[]}): any[] {
if (!products) return [];
if (!args) return products;
return products.filter((pr: any) => {
for(let field in args) {
if(args[field ].indexOf(pr[field]) === -1) {
return false;
}
}
return true;
});
}
}
在我的 app.module.ts 我有(为简洁起见减少):
import { FilterProducts } from '../pages/products/productsFilter.pipe';
@NgModule({
declarations: [
FilterProducts
]
})
在我的产品组件中我有:
public filterArgs : {[field : string] : string[]} = {};
constructor() { }
addBrandFilter(brands: string[]) {
this.addFilter('brand', brands);
}
addFilter(field: string, values: string[]): void {
this.filterArgs[field] = values;
}
然后在我的 NgFor 上有(为简洁起见减少):
*ngFor="let product of products | filterProducts: filterArgs;"
<li class="search-filters__item" (click)="addBrandFilter(['Brand Name'])">Brand Name</li>
我使用模板进行过滤设置的方式包括价格、品牌和类型。其中有一些用户可以单击的按钮,例如价格为 0-50 或 50-100 等。理想情况下,我希望能够同时应用这些按钮。因此将选择 0-50 和 50-100 并适当过滤 ngFor。
有谁能给我一些关于如何实现这一点的建议吗?我到处搜索,只能根据搜索框或下拉列表找到管道。
编辑
我现在更新了这个以反映@PierreDuc 给我的帮助。我现在正在努力将相关过滤器传递给 filterArgs。
编辑 2
感谢@PierreDuc,我现在再次更新了这个以反映进度。目前 ngFor 不过滤通过(点击)传递的品牌名称。
提前致谢。
您声明您的 filterArgs
是一个字符串数组。在这种情况下,您应该将过滤器更改为:
@Pipe({
name: 'filterProducts'
})
export class FilterProducts implements PipeTransform {
transform(products: any[], field : string, value : string[]): any[] {
if (!products) return [];
if (!value) return products;
return products.filter((pr: any) => {
return value.indexOf(pr[field]) > -1
});
}
}
你可以这样称呼:
*ngFor="let product of products | filterProducts: 'name' : ['cup', 'tea']"
这将 return 所有名称为 cup
或 tea
的产品。如果适用于您,请注意区分大小写
要过滤多个属性,您最好将 {field : values}
对象发送到管道:
要使用您的评论:
let filterArgs : {[field : string] : string[]} = {
name : ['brand', 'otherbrand'],
type : ['A', 'B']
};
然后在你的管道中使用这个:
*ngFor="let product of products | filterProducts: filterArgs"
你的管道变成这样:
@Pipe({
name: 'filterProducts'
})
export class FilterProducts implements PipeTransform {
transform(products: any[], args: {[field : string] : string[]}): any[] {
if (!products) return [];
if (!args) return products;
return products.filter((pr: any) => {
for(let field in args) {
if(args[field ].indexOf(pr[field]) === -1) {
return false;
}
}
return true;
});
}
}
对于价格评估,我建议您构建一个不同的管道,您可以在其中给出最大和最小设置并将其与产品价格进行比较
更新
作为对代码的更新,您应该在构造函数中分配 class 属性,而不是局部变量。 filterArds 是一个对象,而不是数组。所以不需要像你那样初始化它:
public filterArgs : {[field : string] : string[]} = {};
constructor() { }
addBrandFilter(brands: string[]) {
this.addFilter('brand', brands);
}
addFilter(field: string, values: string[]): void {
this.filterArgs[field] = values;
}