Javascript 定制管道产品过滤器?

Javascript 定制管道产品过滤器?,javascript,angular,ionic-framework,angular-filters,angular2-pipe,Javascript,Angular,Ionic Framework,Angular Filters,Angular2 Pipe,因此,我试图实现的是能够在NgFor上切换多个过滤器,并在每次打开或关闭过滤器时进行更新 我有一根管子: import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'filterProducts' }) export class FilterProducts implements PipeTransform { transform(products: any[], args: {[field : str

因此,我试图实现的是能够在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中,我有(为简洁起见减少了):

在我的产品组件中,我有:

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=“让产品中的产品|过滤器产品:过滤器RGS;”
品牌名称
我让模板进行过滤设置的方式,它有价格、品牌和类型的子部分。其中有一些按钮,用户可以点击,如价格为0-50或50-100等。理想情况下,我希望这些能够同时应用。因此,应选择0-50和50-100,并适当过滤ngFor

有谁能给我一些关于如何做到这一点的建议吗?我到处都搜索过,只能根据搜索框或下拉列表找到管道

编辑

我现在更新了这个,以反映@PierreDuc给我的帮助。我现在正在努力将相关的过滤器传递到filterArgs

编辑2

由于@PierreDuc,我现在再次更新了此文件,以反映进度。当前,ngFor未过滤到通过(单击)传递的品牌名称


提前谢谢

您声明您的
过滤器args
是一个字符串数组。在这种情况下,您应该将过滤器更改为:

@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']"
这将返回名称为
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?比如说,我想看看价格在0英镑到50英镑之间、名称为“品牌”且为“TypeA”的产品?非常感谢,我已经实现了这一点,但是当我尝试运行addBrandFilter函数时,我现在遇到了错误“无法读取未定义的属性'name'”(请参阅更新的代码)。有什么想法吗?:)再次更新我的答案;)非常感谢。现在看来ngFor对过滤器没有反应。当我启动addBrandFilter传入字符串时,当我启动console.log filterArgs out时,字符串作为brand:“string”出现在那里。但是筛选器没有反应:(-并且该值确实存在于ngFor中。您应该将字符串作为数组传递,以便可以筛选多个品牌:
addBrandFilter(['brand1','brand2');
@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;
        });
    }
}
public filterArgs : {[field : string] : string[]} = {};

constructor() { }

addBrandFilter(brands: string[]) {
    this.addFilter('brand', brands);
}

addFilter(field: string, values: string[]): void {
    this.filterArgs[field] = values;
}