1

所以我試圖實現的是能夠在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。

EDIT 2

現在我已經再次更新這反映進度感謝@PierreDuc。目前,ngFor不會過濾通過(點擊)傳遞的品牌名稱。

在此先感謝。

回答

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; 
     }); 
    } 
} 

對於價格的評估,我建議你建立一個不同的管道,在那裏你可以給一個最大值和最小值的設置和比較,爲產品

更新

的價格作爲更新你的代碼,你應該分配類屬性,而不是你的構造函數中的局部變量。 filterArds是一個對象,而不是一個數組。所以不需要像你這樣初始化它:

public filterArgs : {[field : string] : string[]} = {}; 

constructor() { } 

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

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

謝謝你,這已經很好地工作了。我如何將它轉換爲能夠從一組過濾器中單擊以過濾ngFor?假設我希望看到價格在0到50英鎊之間的產品,名稱是「Brand」,並且是「TypeA」? (對不起,如果沒有意義)。 – Alsh

+0

我已經更新了我的答案,但未經測試的代碼:) – PierreDuc

+0

非常感謝,我已經實現了這一點,但是當我嘗試運行addBrandFilter函數時,我現在收到錯誤「Can not read property name'of undefined」更新的代碼)。有任何想法嗎? :) – Alsh