1

私が達成しようとしているのは、フィルタがオンまたはオフに切り替わる度に更新されるNgForで複数のフィルタを切り替えることができることです。私は(簡潔にするため縮小)している私のapp.module.tsでカスタムパイプ製品フィルター?

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

私はこのパイプ持っている私の製品コンポーネントで

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が適切にフィルタリングされます。

これを達成する方法について誰でも私に助言を与えることができますか?私はどこでも検索し、検索ボックスやドロップダウンに基づいてパイプを見つけることができます。

EDIT

私は今@PierreDucによって私に与えられた助けを反映するために、これを更新しました。私は現在、関連するフィルタをfilterArgsに渡すのに苦労しています。私は今進行に@PierreDucへの感謝を反映するために、再度これを更新した

EDIT 2

。現在、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" 

そして、これまでお使いのパイプの変更:

私はあなたが最大と最小の設定を与えるとのアップデートとして、製品の価格

更新

にそれを比較することができます別のパイプを構築示唆価格評価のために10

@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、ブランド名が "TypeA"の製品を見たいとしますか? (それが理にかなっていれば申し訳ありません)。 – Alsh

+0

私の答えはまだテストされていないコードを更新しました:) – PierreDuc

+0

ありがとう、私はこれを実装しましたが、 "addBrandFilter関数を実行しようとすると、"未定義のプロパティ 'name'を読み込めません。更新されたコード)。何か案は? :) – Alsh