定制管道产品过滤器?

时间:2017-02-10 14:13:25

标签: 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 : 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不会过滤通过(点击)传递的品牌名称。

提前致谢。

1 个答案:

答案 0 :(得分:1)

您声明您的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']"

这将返回名称为cuptea的所有产品。如果适用于您,请注意区分大小写

要过滤多个属性,最好将{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;
}