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 - соответствующим образом.

Может ли кто-нибудь дать мне несколько советов о том, как достичь этого? Я искал везде и могу найти трубы только на основе поисковых ящиков или выпадающих меню.

EDIT

Я теперь обновил это, чтобы отразить помощь, оказанную мне @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']" 

Это возвращает все продукты, где их имя 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; 
     }); 
    } 
} 

Для оценки цен я предлагаю вам построить другую трубу, где вы можете дать максимум и минимум настроек, и сравнить с ценой продукта

обновление

В качестве обновления для ваш код, вы должны назначить свойство класса, а не локальную переменную в своем конструкторе. И filterArds - это объект, а не массив. Поэтому нет необходимости инициализировать его, как вы:

+0

Благодарим вас за это, это прекрасно работало. Как перенести это на возможность щелчка по набору фильтров, чтобы затем фильтровать ngFor? Скажем, я хотел бы видеть продукты, которые от £ 0 - £ 50, имеют название «Бренд» и являются «TypeA»? (Извините, если это не имеет смысла). – Alsh

+0

Я обновил свой ответ, непроверенный код, хотя :) – PierreDuc

+0

Большое спасибо, я внедрил это, но теперь я получаю сообщение об ошибке «Не могу прочитать имя свойства« неопределенного », когда я пытаюсь запустить функцию addBrandFilter (см. обновленный код). Есть идеи? :) – Alsh

 Смежные вопросы

  • Нет связанных вопросов^_^