Как отфильтровать список, используя пользовательский фильтр и флажки в angular 7 - PullRequest
0 голосов
/ 08 января 2020

У меня есть список данных в cardData списке, и я зацикливаюсь на нем, используя ngFor, чтобы отобразить карточку для каждого элемента. Я хочу отфильтровать карты по имени карты, которое записано в свойстве filterName.

У меня также есть собственный фильтр: я использую флажки для выбора filterName. Когда я выбираю один флажок, он работает нормально, но я хочу иметь возможность выбрать несколько флажков и фильтровать соответственно. Буду признателен за помощь.

<div class="card-list cursor-move" cdkDrag *ngFor="let cardDet of cardData | filter:filterName">
<input type="checkbox" value="{{filterDet.title}}" (change)="filterValue($event.target.value,$event.target.checked)">
enter code here

@Pipe({
  name: 'filter',
  pure: false
})
@Injectable()
export class FilterPipe implements PipeTransform {

   /* @param items List of items to filter
    @param term a string term to compare with every property of the list*/

  static filter(items: Array<{ [key: string]: any }>, term: string): Array<{ [key: string]: any }> {

    const toCompare = term.toLowerCase();


    return items.filter(function (item: any) {
      for (const property in item) {
        if (item[property] === null) {
          continue;
        }
        if (item[property].toString().toLowerCase().includes(toCompare)) {
          return true;
        }
      }
      return false;
    });
  }

  transform(items: any, term: string): any {
    if (!term || !items) {
      return items;
    }
    return FilterPipe.filter(items, term);
  }
}
  //filterValue() is called onChange on the checkbox

  filterValue(value,checked){
    console.log(checked);
    if(checked){
      console.log(value);
      this.filterName = value;
    }
    else{
         this.filterName='';
    }

  }

1 Ответ

0 голосов
/ 10 января 2020

Хорошо, здесь нужно сделать две вещи. Во-первых, вам нужно захватить несколько значений из ваших флажков. Прямо сейчас вы просто перезаписываете строку с последним установленным флажком:

filterValue(value,checked) {
   if(checked) {
     this.filterName = value;
   }
   else {
     this.filterName='';
   }
 }

Один из способов сделать это можно, если вы не хотите использовать какие-либо из существующих форм / шаблонов Angular (которые я Настоятельно рекомендуем вам узнать, если вы незнакомы, вот несколько источников, чтобы проверить: 1 , 2 , 3 ), чтобы сделать Array. Давайте представим, что вы сделали один, и он называется filterNameArray. Теперь вы должны переписать свой метод, чтобы сопоставить содержимое filterNameArray с отмеченными флажками:

 filterValue(value,checked) {
   if(checked) { //add to array
     this.filterNameArray.push(value);
   }
   else { //remove from array
     this.filterNameArray = this.filterNameArray.filter(x => x != value);
   }
 }

Как видите, мы добавляем значение к Array, когда оно проверено и удалить его, когда он не проверен. Чтобы удалить его, мы фильтруем Array. Я использовал функцию со стрелкой выше, потому что для некоторых людей она короче и проще для чтения, но если вы не знакомы с функциями стрелок, это эквивалентно этой более простой версии:

function(x, value) {
    if (x == value) {
        return false;
    }
    return true;
}

Когда мы используем это с помощью функции filter Array мы говорим нашему коду запустить эту функцию для каждого элемента в Array (каждый элемент представлен x в моем переписанном методе выше) и вернуть Array, содержащий только значения, которые сделали это, возвращают true. Надеюсь, это имеет смысл, но, пожалуйста, не стесняйтесь задавать мне вопросы. Продолжаем!

Теперь мы можем предположить, что у нас есть Array, который содержит все термины для фильтрации карточек (но помните, что вам все равно нужно пройти это правильно!). Следующим шагом является фильтрация для этого Array вместо string.

return items.filter(function (item: any) {
  for (const property in item) {
    let cardName = item[property].toString().toLowerCase();
    if (item[property] === null) {
      continue;
    }
    if (toCompare.includes(cardName)) {
      return true;
    }
  }
  return false;
});

Я переместил манипуляции со строками над операторами if и сохранил их в let просто так, что я сделал легче читать. С этим изменением фильтр карты просматривает Array и сохраняет карту, если найдено ее имя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...